Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subtraction for https://github.com/trueagi-io/metta-wam/issues/60 #94

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)))
)

Loading