Add when/2 and when_si/2
This commit is contained in:
@@ -39,7 +39,8 @@
|
|||||||
character_si/1,
|
character_si/1,
|
||||||
term_si/1,
|
term_si/1,
|
||||||
chars_si/1,
|
chars_si/1,
|
||||||
dif_si/2]).
|
dif_si/2,
|
||||||
|
when_si/2]).
|
||||||
|
|
||||||
:- use_module(library(lists)).
|
:- use_module(library(lists)).
|
||||||
|
|
||||||
@@ -98,3 +99,31 @@ dif_si(X, Y) :-
|
|||||||
( X \= Y -> true
|
( X \= Y -> true
|
||||||
; throw(error(instantiation_error,dif_si/2))
|
; throw(error(instantiation_error,dif_si/2))
|
||||||
).
|
).
|
||||||
|
|
||||||
|
:- meta_predicate(when_si(+, 0)).
|
||||||
|
|
||||||
|
%% when_si(Condition, Goal).
|
||||||
|
%
|
||||||
|
% Executes Goal when Condition becomes true. Throws an instantiation error if
|
||||||
|
% it can't decide.
|
||||||
|
when_si(Condition, Goal) :-
|
||||||
|
% Taken from https://stackoverflow.com/a/40449516
|
||||||
|
( when_condition_si(Condition) ->
|
||||||
|
( Condition ->
|
||||||
|
Goal
|
||||||
|
; throw(error(instantiation_error,when_si/2))
|
||||||
|
)
|
||||||
|
; throw(error(domain_error(when_condition_si, Condition),_))
|
||||||
|
).
|
||||||
|
|
||||||
|
when_condition_si(Cond) :-
|
||||||
|
var(Cond), !, throw(error(instantiation_error,when_condition_si/2)).
|
||||||
|
when_condition_si(ground(_)).
|
||||||
|
when_condition_si(nonvar(_)).
|
||||||
|
when_condition_si((A, B)) :-
|
||||||
|
when_condition_si(A),
|
||||||
|
when_condition_si(B).
|
||||||
|
when_condition_si((A ; B)) :-
|
||||||
|
when_condition_si(A),
|
||||||
|
when_condition_si(B).
|
||||||
|
|
||||||
|
|||||||
103
src/lib/when.pl
Normal file
103
src/lib/when.pl
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
Provides the predicate `when/2`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:- module(when, [when/2]).
|
||||||
|
|
||||||
|
:- use_module(library(atts)).
|
||||||
|
:- use_module(library(dcgs)).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(lambda)).
|
||||||
|
|
||||||
|
:- attribute when_list/1.
|
||||||
|
|
||||||
|
:- meta_predicate(when(+, 0)).
|
||||||
|
|
||||||
|
%% when(Condition, Goal).
|
||||||
|
%
|
||||||
|
% Executes Goal when Condition becomes true.
|
||||||
|
when(Condition, Goal) :-
|
||||||
|
( when_condition(Condition) ->
|
||||||
|
( Condition ->
|
||||||
|
Goal
|
||||||
|
; term_variables(Condition, Vars),
|
||||||
|
maplist(
|
||||||
|
[Goal, Condition]+\Var^(
|
||||||
|
get_atts(Var, when_list(Whens0)) ->
|
||||||
|
Whens = [when(Condition, Goal) | Whens0],
|
||||||
|
put_atts(Var, when_list(Whens))
|
||||||
|
; put_atts(Var, when_list([when(Condition, Goal)]))
|
||||||
|
),
|
||||||
|
Vars
|
||||||
|
)
|
||||||
|
)
|
||||||
|
; throw(error(domain_error(when_condition, Condition),_))
|
||||||
|
).
|
||||||
|
|
||||||
|
when_condition(Cond) :-
|
||||||
|
% Should this be delayed?
|
||||||
|
var(Cond), !, throw(error(instantiation_error,when_condition/1)).
|
||||||
|
when_condition(ground(_)).
|
||||||
|
when_condition(nonvar(_)).
|
||||||
|
when_condition((A, B)) :-
|
||||||
|
when_condition(A),
|
||||||
|
when_condition(B).
|
||||||
|
when_condition((A ; B)) :-
|
||||||
|
when_condition(A),
|
||||||
|
when_condition(B).
|
||||||
|
|
||||||
|
remove_goal([], _, []).
|
||||||
|
remove_goal([G0|G0s], Goal, Goals) :-
|
||||||
|
( G0 == Goal ->
|
||||||
|
remove_goal(G0s, Goal, Goals)
|
||||||
|
; Goals = [G0|Goals1],
|
||||||
|
remove_goal(G0, Goal, Goals1)
|
||||||
|
).
|
||||||
|
|
||||||
|
vars_remove_goal(Vars, Goal) :-
|
||||||
|
maplist(
|
||||||
|
Goal+\Var^(
|
||||||
|
get_atts(Var, when_list(Whens0)) ->
|
||||||
|
remove_goal(Whens0, Goal, Whens),
|
||||||
|
( Whens = [] ->
|
||||||
|
put_atts(Var, -when_list(_))
|
||||||
|
; put_atts(Var, when_list(Whens))
|
||||||
|
)
|
||||||
|
; true
|
||||||
|
),
|
||||||
|
Vars
|
||||||
|
).
|
||||||
|
|
||||||
|
reinforce_goal(Goal0, Goal) :-
|
||||||
|
Goal = (
|
||||||
|
term_variables(Goal0, Vars),
|
||||||
|
when:vars_remove_goal(Vars, Goal0),
|
||||||
|
Goal0
|
||||||
|
).
|
||||||
|
|
||||||
|
verify_attributes(Var, Value, Goals) :-
|
||||||
|
( get_atts(Var, when_list(Whens)) ->
|
||||||
|
( var(Value) ->
|
||||||
|
( get_atts(Value, when_list(WhensValue)) ->
|
||||||
|
append(Whens, WhensValue, WhensNew),
|
||||||
|
put_atts(Value, when_list(WhensNew))
|
||||||
|
; put_atts(Value, when_list(Whens))
|
||||||
|
),
|
||||||
|
Goals = []
|
||||||
|
; maplist(reinforce_goal, Whens, Goals)
|
||||||
|
)
|
||||||
|
; Goals = []
|
||||||
|
).
|
||||||
|
|
||||||
|
gather_when_goals([], _) --> [].
|
||||||
|
gather_when_goals([When|Whens], Var) -->
|
||||||
|
( { term_variables(When, [V0|_]), Var == V0 } ->
|
||||||
|
[when:When]
|
||||||
|
; []
|
||||||
|
),
|
||||||
|
gather_when_goals(Whens, Var).
|
||||||
|
|
||||||
|
attribute_goals(Var) -->
|
||||||
|
{ get_atts(Var, when_list(Whens)) },
|
||||||
|
gather_when_goals(Whens, Var),
|
||||||
|
{ put_atts(Var, -when_list(_)) }.
|
||||||
Reference in New Issue
Block a user