]> Repositorios git - scryer-prolog.git/commitdiff
re: #80, #52
authorMark Thom <[email protected]>
Tue, 2 Apr 2019 04:05:30 +0000 (22:05 -0600)
committerMark Thom <[email protected]>
Tue, 2 Apr 2019 04:05:30 +0000 (22:05 -0600)
Cargo.toml
src/prolog/lib/builtins.pl
src/prolog/machine/mod.rs
src/tests.rs

index 7adce29d3a3b5603175c9f1d26487c0e8c200403..5a10a986709021074dacc930d3dbedbecaaaa3f1 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.35"
+version = "0.8.36"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
@@ -14,7 +14,7 @@ cfg-if = "0.1.7"
 downcast = "0.10.0"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.8.11"
+prolog_parser = "0.8.12"
 readline_rs_compat = { version = "0.1.7", optional = true }
 ref_thread_local = "0.0.0"
 
index 3639baf7e2dd2d29981698e4067f9d741a96026d..7357d230c0ac4a65e0d183298b13f52e841c84af 100644 (file)
@@ -110,7 +110,7 @@ set_prolog_flag(double_quotes, chars) :-
 set_prolog_flag(double_quotes, atom) :-
     !, '$set_double_quotes'(atom). % 7.11.2.5, list of char codes (UTF8).
 set_prolog_flag(double_quotes, codes) :-
-    !, '$set_double_quotes'(codes). 
+    !, '$set_double_quotes'(codes).
 set_prolog_flag(double_quotes, Value) :-
     throw(error(domain_error(flag_value, double_quotes + Value),
                set_prolog_flag/2)). % 8.17.1.3 e
@@ -427,14 +427,32 @@ iterate_variants([V-Solution|GroupSolutions], V, Solution).
 iterate_variants([_|GroupSolutions], Ws, Solution) :-
     iterate_variants(GroupSolutions, Ws, Solution).
 
+rightmost_power(Term, FinalTerm, Xs) :-
+    (  Term = X ^ Y
+    -> (  var(Y) -> FinalTerm = Y, Xs = [X]
+       ;  Xs = [X | Xss], rightmost_power(Y, FinalTerm, Xss)
+       )
+    ;  Xs = [], FinalTerm = Term
+    ).
+
+findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :-
+    (  nonvar(Goal), Goal = _ ^ _ ->
+       rightmost_power(Goal, Goal1, ExistentialVars0),
+       term_variables(ExistentialVars0, ExistentialVars),
+       set_difference(Witnesses0, ExistentialVars, Witnesses),
+       findall(Witnesses-Template, Goal1, PairedSolutions)
+    ;  Witnesses = Witnesses0,
+       findall(Witnesses-Template, Goal, PairedSolutions)
+    ).
+    
 bagof(Template, Goal, Solution) :-
     error:can_be(list, Solution),
     term_variables(Template, TemplateVars0),
     term_variables(Goal, GoalVars0),
     sort(TemplateVars0, TemplateVars),
     sort(GoalVars0, GoalVars),
-    set_difference(GoalVars, TemplateVars, Witnesses),
-    findall(Witnesses-Template, Goal, PairedSolutions0),
+    set_difference(GoalVars, TemplateVars, Witnesses0),
+    findall_with_existential(Template, Goal, PairedSolutions0, Witnesses0, Witnesses),
     keysort(PairedSolutions0, PairedSolutions),
     group_by_variants(PairedSolutions, GroupedSolutions),
     iterate_variants(GroupedSolutions, Witnesses, Solution).
@@ -450,8 +468,8 @@ setof(Template, Goal, Solution) :-
     term_variables(Goal, GoalVars0),
     sort(TemplateVars0, TemplateVars),
     sort(GoalVars0, GoalVars),
-    set_difference(GoalVars, TemplateVars, Witnesses),
-    findall(Witnesses-Template, Goal, PairedSolutions0),
+    set_difference(GoalVars, TemplateVars, Witnesses0),
+    findall_with_existential(Template, Goal, PairedSolutions0, Witnesses0, Witnesses),
     keysort(PairedSolutions0, PairedSolutions),
     group_by_variants(PairedSolutions, GroupedSolutions),
     iterate_variants_and_sort(GroupedSolutions, Witnesses, Solution).
@@ -721,8 +739,9 @@ op_specifier(OpSpec) :- atom(OpSpec),
 op_specifier(OpSpec) :- throw(error(type_error(atom, OpSpec), op/3)).
 
 valid_op(Op) :- atom(Op),
-    (  Op \== (,) -> true
-    ;  throw(error(permission_error(modify, operator, (,)), op/3)) % 8.14.3.3 j), k).
+    (  Op == (,) -> throw(error(permission_error(modify, operator, (,)), op/3)) % 8.14.3.3 j), k).
+    ;  Op == '|' -> throw(error(permission_error(create, operator, (|)), op/3)) % www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#72
+    ;  true
     ).
 
 op_(Priority, OpSpec, Op) :- '$op'(Priority, OpSpec, Op).
index 5b7dc287b32be48f2e52a4c3957a8edefea2fb8e..4bc5c852a994cc6ea0dd715478bfa29ac1af9339 100644 (file)
@@ -427,9 +427,9 @@ impl Machine {
         for (var, addr) in sorted_vars {
             let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
 
-            if addr.is_ref() {
-                continue;
-            }
+//            if addr.is_ref() {
+//                continue;
+//            }
 
             output = self.machine_st.print_var_eq(var.clone(), addr, var_dir, output);
         }
index e854f153be277f6a8f66e35e58159e361a181486..ab71c48575189d29b4576094b9e849e48302a98d 100644 (file)
@@ -1750,12 +1750,12 @@ fn test_queries_on_builtins()
 
     assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
-                            ["L = [_184]", "X = _0", "Y = 1", "Z = _6"]]);
+                            ["L = [_188]", "X = _0", "Y = 1", "Z = _6"]]);
 
     submit(&mut wam, "a(1, f(_)). a(2, f(_)).");
 
     assert_prolog_success!(&mut wam, "?- bagof(X, a(X, Y), L).",
-                           [["L = [1, 2]", "X = _0", "Y = f(_150)"]]);
+                           [["L = [1, 2]", "X = _0", "Y = f(_154)"]]);
 
     assert_prolog_success!(&mut wam, "?- setof(X, (X = 1 ; X = 2), S).",
                            [["S = [1, 2]", "X = _0"]]);
@@ -1767,7 +1767,7 @@ fn test_queries_on_builtins()
                             ["L = [1]", "Y = 2"]]);
     assert_prolog_success!(&mut wam, "?- setof(X, (X=Y; X=Z; Y=1), L).",
                            [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
-                            ["L = [_184]", "X = _0", "Y = 1", "Z = _6"]]);
+                            ["L = [_188]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]);
     assert_prolog_failure!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)]).");
     assert_prolog_success!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).",
                            [["U = a", "V = a", "X = _0"]]);
@@ -1790,6 +1790,18 @@ fn test_queries_on_builtins()
     assert_prolog_success!(&mut wam, "?- catch(findall(X, 4, S0, S1), error(type_error(callable, 4), _), true).",
                            [["S0 = _3", "S1 = _4", "X = _1"]]);
 
+    // bagof & setof with existential variables.
+    assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
+                           [["S = [1, 2]", "X = _0", "Y = _5"]]);
+    assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
+                           [["S = [1, _240, 2]", "X = _0", "Y = _5"]]);
+
+    assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
+                           [["S = [1, 2]", "X = _0", "Y = _5"]]);
+    assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
+                           [["S = [_240, 1, 2]", "X = _0", "Y = _5"]]);
+    assert_prolog_success!(&mut wam, "?- setof(X, (exists(U,V) ^ member(X, [V,U,f(U),f(V)])), [a,b,f(b),f(a)]).");
+        
     submit(&mut wam, "
 :- dynamic(cat/0).
 cat.