mech_set/relations/
proper_superset.rs1use crate::*;
2
3use indexmap::set::IndexSet;
4use mech_core::set::MechSet;
5
6#[derive(Debug)]
12struct SetProperSupersetFxn {
13 lhs: Ref<MechSet>,
14 rhs: Ref<MechSet>,
15 out: Ref<bool>,
16}
17
18impl MechFunctionFactory for SetProperSupersetFxn {
19 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
20 match args {
21 FunctionArgs::Binary(out, arg1, arg2) => {
22 let lhs: Ref<MechSet> = unsafe { arg1.as_unchecked() }.clone();
23 let rhs: Ref<MechSet> = unsafe { arg2.as_unchecked() }.clone();
24 let out: Ref<bool> = unsafe { out.as_unchecked() }.clone();
25 Ok(Box::new(SetProperSupersetFxn { lhs, rhs, out }))
26 },
27 _ => Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: args.len() }, None).with_compiler_loc()),
28 }
29 }
30}
31
32impl MechFunctionImpl for SetProperSupersetFxn {
33 fn solve(&self) {
34 unsafe {
35 let out_ptr: &mut bool = &mut *(self.out.as_mut_ptr());
36 let lhs_ptr: &MechSet = &*(self.lhs.as_ptr());
37 let rhs_ptr: &MechSet = &*(self.rhs.as_ptr());
38 *out_ptr = lhs_ptr.set.is_superset(&rhs_ptr.set) && (lhs_ptr.set.len() > rhs_ptr.set.len());
40 }
41 }
42 fn out(&self) -> Value { Value::Bool(self.out.clone()) }
43 fn to_string(&self) -> String { format!("{:#?}", self) }
44}
45
46#[cfg(feature = "compiler")]
47impl MechFunctionCompiler for SetProperSupersetFxn {
48 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
49 let name = "SetProperSupersetFxn".to_string();
50 compile_binop!(name, self.out, self.lhs, self.rhs, ctx, FeatureFlag::Builtin(FeatureKind::ProperSuperset));
52 }
53}
54
55register_descriptor! {
56 FunctionDescriptor {
57 name: "SetProperSupersetFxn",
58 ptr: SetProperSupersetFxn::new,
59 }
60}
61
62fn set_proper_superset_fxn(lhs: Value, rhs: Value) -> MResult<Box<dyn MechFunction>> {
63 match (lhs, rhs) {
64 (Value::Set(lhs), Value::Set(rhs)) => {
65 Ok(Box::new(SetProperSupersetFxn { lhs: lhs.clone(), rhs: rhs.clone(), out: Ref::new(false) }))
66 },
67 x => Err(MechError2::new(
68 UnhandledFunctionArgumentKind2 {
69 arg: (x.0.kind(), x.1.kind()),
70 fxn_name: "set/proper-superset".to_string(),
71 }, None
72 ).with_compiler_loc()),
73 }
74}
75
76pub struct SetProperSuperset {}
77impl NativeFunctionCompiler for SetProperSuperset {
78 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
79 if arguments.len() != 2 {
80 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: arguments.len() }, None).with_compiler_loc());
81 }
82 let lhs = arguments[0].clone();
83 let rhs = arguments[1].clone();
84 match set_proper_superset_fxn(lhs.clone(), rhs.clone()) {
85 Ok(fxn) => Ok(fxn),
86 Err(_) => {
87 match (lhs, rhs) {
88 (Value::MutableReference(lhs), Value::MutableReference(rhs)) => set_proper_superset_fxn(lhs.borrow().clone(), rhs.borrow().clone()),
89 (lhs, Value::MutableReference(rhs)) => set_proper_superset_fxn(lhs.clone(), rhs.borrow().clone()),
90 (Value::MutableReference(lhs), rhs) => set_proper_superset_fxn(lhs.borrow().clone(), rhs.clone()),
91 x => Err(MechError2::new(
92 UnhandledFunctionArgumentKind2 { arg: (x.0.kind(), x.1.kind()), fxn_name: "set/proper-superset".to_string() },
93 None
94 ).with_compiler_loc()),
95 }
96 }
97 }
98 }
99}
100
101register_descriptor! {
102 FunctionCompilerDescriptor {
103 name: "set/proper-superset",
104 ptr: &SetProperSuperset{},
105 }
106}