From: Adrián Arroyo Calle Date: Wed, 21 Dec 2022 20:29:22 +0000 (+0100) Subject: Merge branch 'master' into docs-builtins X-Git-Tag: v0.9.2~206^2~3 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=f2d041ea2373babb58135ea0b4107fb9d49d1a19;p=scryer-prolog.git Merge branch 'master' into docs-builtins --- f2d041ea2373babb58135ea0b4107fb9d49d1a19 diff --cc src/lib/builtins.pl index 89270f6f,d7f3c536..aef9b32b --- a/src/lib/builtins.pl +++ b/src/lib/builtins.pl @@@ -256,38 -158,34 +256,45 @@@ G1 -> G2 :- control_entry_point((G1 -> :- non_counted_backtracking staggered_if_then/2. staggered_if_then(G1, G2) :- - '$get_staggered_cp'(B), call(G1), - '$set_cp'(B), + !, call(G2). +%% ;(G1, G2) +% +% Disjunction (or) G1 ; G2 :- control_entry_point((G1 ; G2)). :- non_counted_backtracking staggered_sc/2. - staggered_sc(G, _) :- call(G). + staggered_sc(G, _) :- + ( nonvar(G), + G = '$call'(builtins:staggered_if_then(G1, G2)) -> + call(G1), + !, + call(G2) + ; call(G) + ). staggered_sc(_, G) :- call(G). +%% !. +% +% Cut operator. Discards the choicepoints created since entering the prediacate in which the operator appears. +% Using cut is not recommended as it introduces a non-declarative flow of programming and makes it more difficult +% to reason about the programs. Also restricts the ability to run the program with alternative execution strategies !. :- non_counted_backtracking set_cp/1. set_cp(B) :- '$set_cp'(B). +%% ,(G1, G2) +% +% Conjuction (and) ','(G1, G2) :- control_entry_point((G1, G2)). + :- non_counted_backtracking control_entry_point/1. control_entry_point(G) :- @@@ -941,30 -739,12 +938,29 @@@ findall_with_existential(Template, Goal :- non_counted_backtracking bagof/3. +%% bagof(Template, Goal, Solution). +% +% Unify Solution with a list of alternatives of the variables in Template coming from calling Goal. +% If Goal has no solutions, the predicate fails. +% If free variables that are not in Template appear in Goal, the predicate will backtrack over +% the alternatives of those free variables. However, you can use the syntax `Var^Goal` to not bind +% Var in Goal and prevent that. +% +% Example: +% +% f(1, 3). +% f(2, 4). +% ?- bagof(X, f(X, Y), Bag). +% Y = 3, Bag = [1], +% ; Y = 4, Bag = [2]. +% ?- bagof(X, Y^f(X, Y), Bag). +% Bag = [1,2]. 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, Witnesses0), + term_variables(Template, TemplateVars), + term_variables(Goal, GoalVars), + term_variables(TemplateVars+GoalVars, TGVs), + lists:append(TemplateVars, Witnesses0, TGVs), findall_with_existential(Template, Goal, PairedSolutions0, Witnesses0, Witnesses), keysort(PairedSolutions0, PairedSolutions), group_by_variants(PairedSolutions, GroupedSolutions), @@@ -986,22 -766,12 +982,21 @@@ iterate_variants_and_sort([_|GroupSolut :- non_counted_backtracking setof/3. +%% setof(Template, Goal, Solution). +% +% Similar to bagof/3 but Solution is sorted and duplicates are removed. Example: +% +% f(1, 2). +% f(1, 3). +% f(2, 4). +% ?- setof(X, Y^f(X, Y), Set). +% Set = [1, 2]. setof(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, Witnesses0), + term_variables(Template, TemplateVars), + term_variables(Goal, GoalVars), + term_variables(TemplateVars+GoalVars, TGVs), + lists:append(TemplateVars, Witnesses0, TGVs), findall_with_existential(Template, Goal, PairedSolutions0, Witnesses0, Witnesses), keysort(PairedSolutions0, PairedSolutions), group_by_variants(PairedSolutions, GroupedSolutions),