mech_set/relations/
subset.rs

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