-
Notifications
You must be signed in to change notification settings - Fork 136
/
Copy pathwhen.pl
106 lines (93 loc) · 2.71 KB
/
when.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
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)).
:- use_module(library(format)).
:- use_module(library(debug)).
:- 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(G0s, 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(_)) }.