From 785d8d28e3202a24e8c69363329247235b24a0ec Mon Sep 17 00:00:00 2001 From: Paulo Moura Date: Wed, 3 Apr 2019 11:58:29 +0100 Subject: [PATCH] add de facto standard forall/2 predicate as a built-in predicate --- README.md | 3 ++- src/prolog/lib/builtins.pl | 5 ++++- src/tests.rs | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6f30424d..fde73737 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Extend Scryer Prolog to include the following, among other features: - [x] `call_residue_vars/2` - [x] `if_` and related predicates, following the developments of the paper "Indexing `dif/2`". -- [x] All-solutions predicates (`findall/{3,4}`, `bagof/3`, `setof/3`). +- [x] All-solutions predicates (`findall/{3,4}`, `bagof/3`, `setof/3`, `forall/2`). - [x] Clause creation and destruction (`asserta/1`, `assertz/1`, `retract/1`, `abolish/1`) with logical update semantics. - [x] Backtrackable and non-backtrackable global variables via `bb_get/2` @@ -182,6 +182,7 @@ The following predicates are built-in to Scryer. * `false/0` * `findall/{3,4}` * `float/1` +* `forall/2` * `freeze/2` * `functor/3` * `gen_int/1` diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 24711315..8756c5d0 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -10,7 +10,7 @@ bb_get/2, bb_put/2, call_cleanup/2, call_with_inference_limit/3, catch/3, clause/2, current_predicate/1, current_prolog_flag/2, expand_goal/2, - expand_term/2, findall/3, findall/4, halt/0, once/1, op/3, + expand_term/2, findall/3, findall/4, forall/2, halt/0, once/1, op/3, repeat/0, retract/1, set_prolog_flag/2, setof/3, setup_call_cleanup/3, term_variables/2, throw/1, true/0, false/0, write/1, write_canonical/1, writeq/1, write_term/2]). @@ -405,6 +405,9 @@ findall(Template, Goal, Solutions0, Solutions1) :- Error, ( truncate_lh_to(LhLength), throw(Error) ))). +forall(Generate, Test) :- + \+ (Generate, \+ Test). + set_difference([X|Xs], [Y|Ys], Zs) :- X == Y, !, set_difference(Xs, [Y|Ys], Zs). set_difference([X|Xs], [Y|Ys], [X|Zs]) :- diff --git a/src/tests.rs b/src/tests.rs index ab71c485..c925ce84 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1802,6 +1802,13 @@ fn test_queries_on_builtins() [["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)])."); + assert_prolog_failure!(&mut wam, "?- forall(true, fail)."); + assert_prolog_success!(&mut wam, "?- forall(fail, true)"); + assert_prolog_success!(&mut wam, "?- catch(forall(_, true), error(instantiation_error, _), true)."); + assert_prolog_success!(&mut wam, "?- catch(forall(true, _), error(instantiation_error, _), true)."); + assert_prolog_success!(&mut wam, "?- catch(forall(1, true), error(type_error(callable, 1), _), true)."); + assert_prolog_success!(&mut wam, "?- catch(forall(true, 1), error(type_error(callable, 1), _), true)."); + submit(&mut wam, " :- dynamic(cat/0). cat. -- 2.54.0