Skip to content

Commit

Permalink
subtraction for #60
Browse files Browse the repository at this point in the history
  • Loading branch information
TeamSPoon committed Aug 20, 2024
1 parent 070acd8 commit c81ed31
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/canary/metta_corelib.pl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@
% metta_atom_corelib_types( [:, charsToString [-> 'Expression' 'Atom']]).
% metta_atom_corelib_types( [:, format-args [-> 'Atom' 'Expression' 'Atom']]).

metta_atom_corelib_types( [:, 'unique', [->, 'Atom', 'Atom']]).
metta_atom_corelib_types( [:, 'subtraction', [->, 'Atom', 'Atom', 'Atom']]).

metta_atom_corelib_types( [:, 'get-metatype', [->, 'Atom', 'Atom']]).
metta_atom_corelib_types( [:, 'get-type0', [->, 'Atom', 'Atom']]).
metta_atom_corelib_types( [:, 'get-ftype', [->, 'Atom', 'Atom']]).
Expand Down
23 changes: 23 additions & 0 deletions src/canary/metta_eval.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1650,6 +1650,29 @@
no_repeats_var(YY),
eval_20(Eq,RetType,Depth,Self,Eval,RetVal),YY=Vars.


eval_20(Eq,RetType,Depth,Self,['subtraction',Eval1,Eval2],RetVal):- !,
lazy_subtraction(RetVal1^eval_args(Eq,RetType,Depth,Self,Eval1,RetVal1),
RetVal2^eval_args(Eq,RetType,Depth,Self,Eval2,RetVal2),
RetVal).

%% lazy_subtraction(+E1_Call1, +E2_Call2, -E) is nondet.
% - Performs a subtraction operation using lazy evaluation.
% - It subtracts elements generated by Call2 from those generated by Call1.
% Arguments:
% - E1^Call1: The first goal (Call1) generating elements (E1).
% - E2^Call2: The second goal (Call2) generating elements (E2).
% - E: The resulting element after subtracting elements of the second set from the first set.
lazy_subtraction(E1^Call1, E2^Call2, E1) :-
% Step 1: Evaluate Call1 to generate E1
call(Call1),
% Step 2: Use lazy_findall/3 to declare that all elements satisfying Call2 are supposedly in List2
lazy_findall(E2, Call2, List2),
% Step 3: Perform the subtraction logic
% Only return E1 if it is not a member of List2
\+ (member(E2, List2), E1 = E2).


eval_20(Eq,RetType,Depth,Self,PredDecl,Res):-
Do_more_defs = do_more_defs(true),
clause(eval_21(Eq,RetType,Depth,Self,PredDecl,Res),Body),
Expand Down
5 changes: 5 additions & 0 deletions src/canary/metta_ontology.pfc.pl
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,11 @@
%properties('&corelib','TupleConcat', [data_structures, qhelp("Concatenates tuples."), concatenation]).
%properties('&corelib','collapseCardinality', [data_structures, qhelp("Collapses structures with cardinality consideration."), manipulation, cardinality]).

% --- Nondet unique,union,intersection,subtraction Operations ---
properties('&corelib','unique', [nondet_sets, qhelp("Makes nondet results unique."), no_repeats_var]).
properties('&corelib','subtraction', [nondet_sets, qhelp("It subtracts elements generated by Call2 from those generated by Call1."), lazy_subtraction]).


% --- String and Character manipulation ---
properties('&corelib','stringToChars', [string_operations, qhelp("Convert a string to a list of chars."), string_to_chars]).
properties('&corelib','charsToString', [string_operations, qhelp("Convert a list of chars to a string."), chars_to_string]).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
;; Test basic subtraction functionality
;; This checks that subtracting (b c) from (a b c d) correctly returns (a d).
!(assertEqual
(subtract (superpose (a b c d)) (superpose (b c)))
(superpose (a d))
)

;; Test subtraction with multiple subsequent lists
;; Here, subtracting (b c) and (d) from (a b c d) should result in (a).
!(assertEqual
(subtract (superpose (a b c d)) (superpose (b c)) (superpose (d)))
(superpose (a))
)

;; Test subtraction with nested structures
;; This test ensures that nested elements like (foo (bar baz)) are handled correctly.
!(assertEqual
(subtract (superpose ((foo bar) (bar baz) qux)) (superpose ((bar baz) qux)))
(superpose ((foo bar)))
)

;; Test subtraction with mixed types
;; This checks that the function handles lists with symbols, numbers, and mixed content.
!(assertEqual
(subtract (superpose (1 2 3 foo bar)) (superpose (2 foo)))
(superpose (1 3 bar))
)

;; Test subtraction with duplicates
;; This test ensures that duplicates are treated correctly.
!(assertEqual
(subtract (superpose (a b b c d)) (superpose (b c)))
(superpose (a b d))
)

;; Test subtraction with `unique` applied outside
;; In this case, `unique` is applied after the subtraction, removing duplicates.
!(assertEqual
(unique (subtract (superpose (a b b c)) (superpose (b c c d))))
(superpose (a))
)

;; Test subtraction with `unique` applied inside
;; In this test, `unique` is applied to each input set before performing the subtraction.
!(assertEqual
(subtract (unique (superpose (a b b c))) (unique (superpose (b c c d))))
(superpose (a))
)

;; Test variable substitution during subtraction
;; This ensures that variables can be used and are properly instantiated during the operation.
!(assertEqual
(subtract (superpose ($x $y)) (superpose (b)))
(superpose ($x $y))
)

;; Test subtraction with empty lists
;; Subtracting an empty list should return the original list.
!(assertEqual
(subtract (superpose (a b c)) (superpose ()))
(superpose (a b c))
)

;; Test subtraction with variables and nested structures
;; This checks how variables interact with nested lists during subtraction.
!(assertEqual
(subtract (superpose ((foo ?x) (bar $y))) (superpose ((bar $y) (foo qux))))
(superpose ((foo ?x)))
)

0 comments on commit c81ed31

Please sign in to comment.