Skip to content

Commit

Permalink
Merge pull request #256 from vsbogd/improve-bindings-api
Browse files Browse the repository at this point in the history
Unit tests to demonstrate the issue with Bindings API
  • Loading branch information
vsbogd authored Mar 18, 2023
2 parents 96aac38 + 18e009f commit 3c59e40
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 7 deletions.
85 changes: 80 additions & 5 deletions lib/src/atom/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -995,17 +995,57 @@ mod test {
}

#[test]
fn match_atoms_with_custom_matcher_implementation() {
fn match_atoms_with_custom_matcher() {
assert_match(
expr!({Rand{}}),
expr!((x)),
expr!( {Rand{}} ),
expr!( (x) ),
vec![bind!{x: expr!({42})}]);
assert_match(
expr!((x)),
expr!({Rand{}}),
expr!( (x) ),
expr!( {Rand{}} ),
vec![bind!{x: expr!({42})}]);
}

#[derive(PartialEq, Clone, Debug, Copy)]
struct ReturnPairInX{}

impl Grounded for ReturnPairInX {
fn type_(&self) -> Atom {
Atom::sym("ReturnPairInX")
}
fn execute(&self, _args: &mut Vec<Atom>) -> Result<Vec<Atom>, ExecError> {
execute_not_executable(self)
}
fn match_(&self, _other: &Atom) -> matcher::MatchResultIter {
let result = vec![ bind!{ x: expr!("B") }, bind!{ x: expr!("C") } ];
Box::new(result.into_iter())
}
}

impl Display for ReturnPairInX {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "ReturnPairInX")
}
}

#[ignore = "An API change in Bindings is required in order to implement this"]
#[test]
fn match_atoms_with_custom_matcher_split_results_by_adding_value() {
let pair = ReturnPairInX{};

assert_match(
expr!( { pair } ("A" x) ),
expr!( s s ),
vec![ bind!{ s: expr!({ pair }), x: expr!("B") },
bind!{ s: expr!({ pair }), x: expr!("C") } ]);

assert_match(
expr!( { pair } y y ),
expr!( s ("A" x) s ),
vec![ bind!{ s: expr!({ pair }), y: expr!("A" x), x: expr!("B") },
bind!{ s: expr!({ pair }), y: expr!("A" x), x: expr!("C") } ]);
}

#[ignore = "Requires sorting inside Bindings to be stable"]
#[test]
fn bindings_match_display() {
Expand Down Expand Up @@ -1083,4 +1123,39 @@ mod test {

assert_eq!(narrow, bind!{ rightB: expr!("A"), rightF: expr!("F"), rightE: expr!(rightE) });
}

#[ignore = "An API change is required in order to implement this"]
#[test]
fn bindings_add_var_value_splits_bindings() {
let mut bindings = Bindings::new();
let pair = ReturnPairInX{};

// ({ x -> B, x -> C } (A $x)) ~ ($s $s)
bindings.add_var_binding(VariableAtom::new("s"), expr!({ pair }));
bindings.add_var_binding(VariableAtom::new("s"), expr!("A" x));

// Bindings::add_var_binding() should return a list of resulting
// Bindings instances.
// assert_eq_no_order!(result,
// vec![ bind!{ s: expr!({ pair }), x: expr!("B") },
// bind!{ s: expr!({ pair }), x: expr!("C") } ]);
}

#[ignore = "An API change is required in order to implement this"]
#[test]
fn bindings_add_var_equality_splits_bindings() {
let mut bindings = Bindings::new();
let pair = ReturnPairInX{};

// ({ x -> B, x -> C } $y $y) ~ ($s (A $x) $s)
bindings.add_var_binding(VariableAtom::new("s"), expr!({ pair }));
bindings.add_var_binding(VariableAtom::new("y"), expr!("A" x));
bindings.add_var_equality(&VariableAtom::new("y"), &VariableAtom::new("s"));

// Bindings::add_var_binding() should return a list of resulting
// Bindings instances.
// assert_eq_no_order!(result,
// vec![ bind!{ s: expr!({ pair }), y: expr!("A" x), x: expr!("B") },
// bind!{ s: expr!({ pair }), y: expr!("A" x), x: expr!("C") } ]);
}
}
6 changes: 4 additions & 2 deletions lib/src/metta/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn add_super_types(space: &dyn Space, sub_types: &mut Vec<Atom>, from: usize) {

fn check_types(actual: &[Vec<Atom>], expected: &[Atom], bindings: &mut Bindings) -> bool {
log::trace!("check_types: actual: {:?}, expected: {:?}, bindings: {}", actual, expected, bindings);
match (actual, expected) {
let matched = match (actual, expected) {
([actual, actual_tail @ ..], [expected, expected_tail @ ..]) => {
actual.iter().map(|actual| {
match_reducted_types(actual, expected, bindings)
Expand All @@ -68,7 +68,9 @@ fn check_types(actual: &[Vec<Atom>], expected: &[Atom], bindings: &mut Bindings)
},
([], []) => true,
_ => false,
}
};
log::trace!("check_types: actual: {:?}, expected: {:?}, bindings: {}, matched: {}", actual, expected, bindings, matched);
matched
}

/// Returns true if passed type is a type of function.
Expand Down

0 comments on commit 3c59e40

Please sign in to comment.