YAP 7.1.0
builtins.yap
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2014 *
8* *
9**************************************************************************
10* *
11* File: boot.yap *
12* Last rev: 8/2/88 *
13* mods: *
14* commen ts: boot file for Prolog *
15* *
16*************************************************************************/
17
18/**
19 @file boot.yap
20 @brief YAP bootstrap
21
22 @defgroup YAPControl Control Predicates
23 @ingroup Builtins
24
25@{
26
27*/
28
29/** @pred 0:P,0:Q is iso, meta
30Conjunction of goals (and).
31
32The conjunction is a fundamental construct of Prolog. Example:
33
34```
35 p(X) :- q(X), r(X).
36```
37
38should be read as `p( _X_) if q( _X_) and r( _X_).
39
40
41*/
42','(X,Y) :-
43 ',':env_choice_point(CP),
44 '$current_module'(M),
45 '$call'(X,CP,(X,Y),M),
46 '$call'(Y,CP,(X,Y),M).
47
48/** @pred 0:P ; 0:Q is iso
49Disjunction of goals (or).
50
51Example:
52
53```
54 p(X) :- q(X); r(X).
55```
56should be read as "p( _X_) if q( _X_) or r( _X_)".
57
58
59*/
60';'((X->A),Y) :- ';',
61 ';':env_choice_point(CP),
62 '$current_module'(M),
63 ( '$execute'(X)
64 ->
65 '$call'(A,CP,(X->A;Y),M)
66 ;
67 '$call'(Y,CP,(X->A;Y),M)
68 ).
69';'((X*->A),Y) :- ';',
70 '$current_module'(M),
71 '$current_module':env_choice_point(CP),
72 (
74 '$execute'(X),
75 cut_at(CP,DCP),
76 '$call'(A,CP,(X*->A;Y),M)
77 ;
78 '$call'(Y,CP,(X*->A;Y),M)
79 ).
80';'(X,Y) :-
81 ';':env_choice_point(CP),
82 '$current_module'(M),
83 ( '$call'(X,CP,(X;Y),M) ; '$call'(Y,CP,(X;Y),M) ).
84
85
86'|'(X,Y) :-
87 '|':env_choice_point(CP),
88 '$current_module'(M),
89 ( '$call'(X,CP,(X|Y),M) ; '$call'(Y,CP,(X|Y),M) ).
90
91/** @pred 0:Condition -> 0:Action is iso
92
93@short If _Condition__ has a solution, call _Action_;
94
95@long
96Read as "if-then-else" or "commit". This operator is similar to the
97conditional operator of imperative languages and can be used alone or
98with an else part as follows:
99
100
101```
102 +P -> +Q
103```
104
105"if P then Q".
106
107
108```
109 +P -> +Q; +R
110```
111
112"if P then Q else R".
113
114These two predicates could be defined respectively in Prolog as:
115
116```
117 (P -> Q) :- P, !, Q.
118```
119and
120
121```
122 (P -> Q; R) :- P, !, Q.
123 (P -> Q; R) :- R.
124```
125if there were no "cuts" in _P_, _Q_ and _R_.
126
127vNote that the commit operator works by "cutting" any alternative
128solutions of _P_.
129
130Note also that you can use chains of commit operators like:
131
132```
133 P -> Q ; R -> S ; T.
134```
135Note that `(->)/2` does not affect the scope of cuts in its
136arguments.
137
138
139*/
140'->'(X,Y) :-
141 '->':env_choice_point(CP),
142 '$current_module'(M),
143 ( '$call'(X,CP,(X->Y),M) -> '$call'(Y,CP,(X->Y),M) ).
144
145
146*->*->/** @pred 0:Condition 0:Action is iso
147
148This construct implements the so-called <em>soft-cut</em>. The control is
149defined as follows:
150 + If _Condition_ succeeds at least once, the
151semantics is the same as ( _Condition_, _Action_).
152
153 + If
154 _Condition_ does not succeed, the semantics is that of (\\+
155 _Condition_, _Else_).
156
157 In other words, if _Condition_
158succeeds at least once, simply behave as the conjunction of
159 _Condition_ and _Action_, otherwise execute _Else_.
160
161The construct _A B_, i.e. without an _Else_ branch, is
162translated as the normal conjunction _A_, _B_.
163
164
165*/
166'*->'(X,Y) :-
167 (X, Y).
168
169
170/** @pred ! is iso
171
172
173Read as "cut". Cuts any choices taken in the current procedure.
174When first found "cut" succeeds as a goal, but if backtracking should
175later return to it, the parent goal (the one which matches the head of
176the clause containing the "cut", causing the clause activation) will
177fail. This is an extra-logical predicate and cannot be explained in
178terms of the declarative semantics of Prolog.
179
180example:
181
182```
183 member(X,[X|_]).
184 member(X,[_|L]) :- member(X,L).
185```
186
187With the above definition
188
189```
190 ?- member(X,[1,2,3]).
191```
192
193will return each element of the list by backtracking. With the following
194definition:
195
196```
197 member(X,[X|_]) :- !.
198 member(X,[_|L]) :- member(X,L).
199```
200
201the same query would return only the first element of the
202list, since backtracking could not "pass through" the cut.
203
204*/
205 :-
206 :parent_choice_point(CP),
207 parent_choice_point:cut_at(0, CP).
208
209/** @pred \+ 0:P is iso, meta
210Negation by failure.
211
212Goal _P_ is not provable. The execution of this predicate fails if
213and only if the goal _P_ finitely succeeds. It is not a true logical
214negation, which is impossible in standard Prolog, but
215"negation-by-failure".
216
217This predicate might be defined as:
218
219```
220 \+(P) :- P, !, fail.
221 \+(_).
222```
223if _P_ did not include "cuts".
224
225If _P_ includes cuts, the cuts are defined to be scoped by _P_: they cannot cut over the calling prredicate.
226
227 ~~~~~~~~~~~~
228 go(P).
229
230:- \+ P, !, fail.
231 \+(_).
232 ~~~~~~~~~~~~
233
234*/
235\+(G) :- \+ '$execute'(G).
236
237not(G) :- \+ '$execute'(G).
238
239
240
241
242/** @pred repeat is iso
243Succeeds repeatedly.
244
245In the next example, `repeat` is used as an efficient way to implement
246a loop. The next example reads all terms in a file:
247```{.prolog}
248 a :- repeat, read(X), write(X), nl, X=end_of_file, !.
249```
250the loop is effectively terminated by the cut-goal, when the test-goal
251`X=end` succeeds. While the test fails, the goals `read(X)`,
252`write(X)`, and `nl` are executed repeatedly, because
253backtracking is caught by the `repeat` goal.
254
255The built-in `repeat/0` could be defined in Prolog by:
256
257```{.prolog}
258
259repeat.
260repeat :- repeat.
261```
262
263The predicate between/3 can be used to iterate for a pre-defined
264number of steps.
265
266*/
267 '$execute' :- '$repeat'.
268
269 '$repeat'.
270 '$repeat'.
271 '$repeat'.
272 '$repeat'.
273 '$repeat'.
274 '$repeat'.
275 '$repeat'.
276 '$repeat'.
277 '$repeat'.
278 '$repeat' :- '$repeat'.
279
280/** @pred + _P_ is nondet
281
282The same as `call( _P_)`. This feature has been kept to provide
283compatibility with C-Prolog. When compiling a goal, YAP
284generates a `call( _X_)` whenever a variable _X_ is found as
285a goal.
286
287```{.prolog}
288 a(X) :- X.
289```
290is converted to:
291
292```{.prolog}
293 a(X) :- call(X).
294```
295
296
297*/
298
299/** @pred call( 0:P ) is iso
300Meta-call predicate.
301
302If _P_ is instantiated to an atom or a compound term, the goal `call(
303_P_)` is executed as if the clause was originally written as _P_
304instead as call( _P_ ), except that any "cut" occurring in _P_ only
305cuts alternatives in the execution of _P_.
306
307Defined as if:
308
309~~~
310call(G) :- '$execute'(G).
311~~~
312*/
313
314/** @pred incore( 0:P )
315
316Alias for call/1
317
318*/
319
320/** @pred once( 0:G) is iso
321
322
323Execute the goal _G_ only once. The predicate is defined by:
324
325```{.prolog}
326 once(G) :- call(G), !.
327```
328
329Note that cuts inside once/1 can only cut the other goals inside
330once/1.
331
332
333*/
334once(G) :-
335 '$execute'(G), '$execute'.
336
337
338(:- G) :- '$execute'(G), '$execute'.
339
340(?- G) :- '$execute'(G).
341
342'$$!'(CP) :- '$cut_by'(CP).
343
344([]).
345
346
347
once( 0:G)
current_choice_point( -CP )