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
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).
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).
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).
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"]]);
["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"]]);
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.