-
Notifications
You must be signed in to change notification settings - Fork 1
/
sitcalc.lgt
150 lines (131 loc) · 4.31 KB
/
sitcalc.lgt
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
:- object(sitcalc,
imports(situation_query),
implements(situation_protocol)).
:- info([ version is 1:1:0
, author is 'Paul Brown'
, date is 2019-11-02
, comment is 'A situation is defined by its history of actions.'
]).
empty(s0).
do(A, S1, S2) :-
^^is_action(A),
A::do(S1, S2).
:- if(current_logtalk_flag(tabling, supported)).
:- table(holds_/2).
:- endif.
:- meta_predicate(holds_(*, *)).
holds_(F, S) :-
% Is a Fluent Case
^^is_fluent(F),
F::holds(S).
holds_(Ob::Pred, S) :-
is_obj_fluent(Ob::Pred),
call(Ob::Pred, S).
holds_(F, _) :- % make this into call(F) for less defaulty, include on strategy
% Is not a Fluent, treat as term
nonvar(F),
\+ ^^is_fluent(F),
\+ is_obj_fluent(F),
catch(call(F), error(existence_error(procedure, _), _), fail).
is_obj_fluent(Ob::Pred) :-
current_object(Ob),
Ob::current_predicate(fluent/1),
Ob::fluent(Func/Ar),
SAr is Ar - 1,
functor(Pred, Func, SAr).
:- public(poss/2).
:- mode(poss(+object, +list), zero_or_one).
:- mode(poss(-object, +list), zero_or_more).
:- info(poss/2,
[ comment is 'True iff. Action is an action and it is possible in the situation.'
, argnames is ['Action', 'Situation']
]).
poss(A, S) :-
^^is_action(A),
A::poss(S).
:- public(prior/2).
:- mode(prior(?term, +term), zero_or_more).
:- info(prior/2,
[ comment is 'Prior situations to the current one (transitive).'
, argnames is ['Situation', 'Prior']
]).
prior(do(_, S), P) :-
S = P.
prior(do(_, S), P) :-
prior(S, P).
:- public(member/2).
:- mode(member(?term, +term), zero_or_more).
:- info(member/2,
[ comment is 'Action is a member, or done in, the Situation term.'
, argnames is ['Action', 'Situation']
]).
member(Action, do(Action, _)).
member(Action, do(_, Prior)) :-
member(Action, Prior).
:- public(memberchk/2).
:- mode(memberchk(+term, +term), zero_or_one).
:- info(memberchk/2,
[ comment is 'Check if the Action is in the Situation term.'
, argnames is ['Action', 'Situation']
]).
memberchk(Action, do(Action, _)) :- !.
memberchk(Action, do(_, Prior)) :-
memberchk(Action, Prior).
:- public(situation_list/2).
:- mode(situation_list(?term, ?list), zero_or_one).
:- info(situation_list/2,
[ comment is 'Convert between the Situation term and a list representation. Will generate unground terms.'
, argnames is ['Situation', 'List']
]).
situation_list(Sit, List) :-
( var(Sit) ->
list_sit(List, H-H, Sit)
; sit_list(Sit, H-H, List)
).
% sit_list assumes non-Sit var, List is difference-list
sit_list(s0, List-[], List).
sit_list(do(A, S), Acc-[A|H], List) :-
sit_list(S, Acc-H, List).
% list_sit assumes Sit var,
% Sit is like a difference list, but
% `do(Action, Hole)-Hole` instead of `.(Elem, Hole)-Hole`
list_sit([], Sit-s0, Sit).
list_sit([A|T], Acc-do(A, H), Sit) :-
list_sit(T, Acc-H, Sit).
:- public(length/2).
:- mode(length(?term, ?int), zero_or_one).
:- info(length/2,
[ comment is 'The number of actions in the Situation term.'
, argnames is ['Situation', 'Length']
]).
length(Sit, Length) :-
( integer(Length) ->
Length >= 0,
make_sit(Length, Sit)
; var(Length),
length(Sit, 0, Length)
).
make_sit(N, Sit) :-
( N =:= 0 ->
Sit = s0
; M is N - 1,
Sit = do(_, Prior),
make_sit(M, Prior)
).
length(s0, Length, Length).
length(do(_, Prior), Acc, Length) :-
Acc2 is Acc + 1,
length(Prior, Acc2, Length).
:- public(executable/1).
:- mode(executable(+term), zero_or_one).
:- mode(executable(-term), zero_or_more).
:- info(executable/1,
[ comment is 'The Situation term is theoretically executable. Will generate situations.'
, argnames is ['Situation']
]).
executable(s0).
executable(do(A, S)) :-
executable(S),
^^is_action(A),
A::poss(S).
:- end_object.