Did you know ... Search Documentation:
Pack dcgutils -- prolog/dcg_core.pl
PublicShow source

This module contains predicates for working with definite clause grammars and the related stateful programming style where state arguments are automatically threaded through sequences of calls. Some useful DCG procedures are also included.

When a predicate is declared with type foo(...)// is Det, any requirements on the type of the DCG state are hidden, i.e. the types of the two extra arguments are hidden. In these cases, the documentation below will sometimes state that the predicate 'runs in the S DCG'.

Types used in this module

We use the following to denote types of terms that can be interpreted as DCG phrases with or without further arguments.

phrase(S)
If P is a term of type phrase(S), then P is a valid DCG phrase when the DCG state is of type S, i.e. phrase(P,S1,S2) is valid Prolog goal when S1 and S2 are of type S. N.B. the type phrase(S) is almost but not quite equivalent to the binary predicate type pred(S,S). All such predicates are valid phrases, but phrases involving braces (e.g. {Goal}), commas, semicolons, and if-then constructs (->) are not equivalent to predicates with two extra arguments.
phrase(A, S)
If P is of type phrase(A,S) and X has type A, then call(P,X) is a valid DCG phrase when the DCG is of type S. This type is equivalent to pred(A,S,S) because the only way to call it is with call//1 inside a DCG or call/3 outside it.
phrase(A, B, S)
If P is of type phrase(A,B) and X and Y are of types A and B respectively, then call(P,X,Y) is a valid DCG phrase. And so on. You get the idea.
 nop// is det
Do nothing. (More neutral than []).
 trans(?Old:S, ?New:S, ?S1:int, ?S2:S) is det
Unifies Old and New with the states S1 and S2 respectively.
 set(S:A, S1:_, S2:A) is det
Set state to S.
 get(S:A, S1:A, S2:A) is det
Get state to S.
 set_with(+G:pred(A), S1:_, S2:A) is det
Set current state using a given callable goal G, which should accept one argument. should be of type pred( -S:A), ie it should set S to the new desired state, which is installed in the DCG state.
 with(S:A, P:phrase(A), S1:B, S2:B) is nondet
Run phrase P starting from state S and discarding the final state, meanwhile preserving the state of the current system, i.e. guarantees S1=S2.
 iso(P:phrase(A), S1:A, S2:A) is nondet
Run phrase P starting with current state but discarding its final state and preserving the current state, so that S1=S2.
 once(G:phrase(_))// is semidet
Call DCG phrase G succeeding at most once.
 repeat// is nondet
Create an infinite number of choice points.
 fail// is nondet
Fails immediately.
 freeze(@V:var, +G:phrase(A), ?S1:A, ?S2:A) is nondet
Suspends the application of DCG goal G to S1 and S2 until variable V is instantiated.
 G1:phrase(S) >> G2:phrase(S)// is nondet
Sequential conjuction of phrases G1 and G2, equivalent to (G1,G2), but sometimes more convenient in terms of operator priorities.
 //(+P1:phrase(A), +P2:phrase(A), ?S1:A, ?S2:A) is nondet
Parallel goal operator - succeeds if both phrases succeeds with the same start and end states. P1 is called first. Note, this can be used to capture the list of terminals matched by another phrase by using Phrase // list(Terms). phrase P, eg.
?- phrase(paren(arb)//list(C),"(hello)world",_)
C = "(hello)".
true
 maybe(P:phrase(_))// is det
Try P, if it fails, then do nothing. If it succeeds, cut choicepoints and continue.
 opt(P:phrase(_))// is nondet
P or nothing. Like maybe but does not cut if P succeeds.
 if(G:pred, P, Q)// is det
 if(G:pred, P)// is det
If Prolog goal call(G) succeeds, do P, otherwise, do Q. if(G,P) is equivalent to if(G,P,nop), i.e. does nothing if P fails.
 exhaust(P:phrase(_))// is det
Run phrase sequentially as many times as possible until it fails. Any choice points left by G are cut.
 until(+Q:pred, +P:phrase(_))// is det
Repeatedly call phrase P and test ordinary Prolog goal Q until Q fails. P and Q are copied together before each iteration, so variables can be shared between them, but are not shared between iterations.
 iterate(+P:phrase(A,A,S), +X:A, -Y:A)// is nondet
Sequentially call P zero or more times, passing in X on the first call and threading the result through subsequent calls, (as well as threading the DCG state in the normal way) ending in Y.
 rep(+N:natural, +P:phrase(_))// is nondet
rep(-N:natural, +P:phrase(_))// is nondet
Equivalent to N sequential copies of phrase P. Free variables in P are not shared between copies. If N is unbound on entry, rep//2 is cautious: it tries gradually increasing N from 0 on backtracking.
 rep_with_sep(+Q:phrase(A), +N:natural, +P:phrase(A))// is nondet
rep_with_sep(+Q:phrase(A), -N:natural, +P:phrase(A))// is nondet
As rep//2, but repeats are interspersed with Q. N must be 1 or greater.
 rep_nocopy(+N:natural, +P:phrase(_))// is nondet
Like rep//2 but does not copy P before calling, so any variables in P are shared between all calls. Also, N cannot be a variable in this implementation.
 seqmap(+P:phrase(A,S), X:list(A))// is nondet
 seqmap(+P:phrase(A,B,S), X:list(A), Y:list(B))// is nondet
 seqmap(+P:phrase(A,B,C,S), X:list(A), Y:list(B), Z:list(C))// is nondet
 seqmap(+P:phrase(A,B,C,D,S), X:list(A), Y:list(B), Z:list(C), W:list(D))// is nondet
 seqmap(+P:phrase(A,B,C,D,E,S), X:list(A), Y:list(B), Z:list(C), W:list(D), V:list(E))// is nondet
seqmap//N is like maplist/N except that P is an incomplete phrase rather an ordinary goal, which is applied to the elements of the supplied lists in order, while threading the DCG state correctly through all the calls.

seqmap//N is very powerful - it is like foldl and mapaccum in functional languages, but with the added flexibility of bidirectional Prolog variables.

See also
- maplist/2.
 seqmap_n(+N:natural, +P:phrase(A), X:list(A))// is nondet
 seqmap_n(+N:natural, +P:phrase(A,B), X:list(A), Y:list(B))// is nondet
 seqmap_n(+N:natural, +P:phrase(A,B,C), X:list(A), Y:list(B), Z:list(C))// is nondet
seqmap_n//.. is like seqmap/N except that the lists of arguments are of length N.
 seqmap_with_sep(+S:phrase, +P:phrase(A), X:list(A))// is nondet
 seqmap_with_sep(+S:phrase, +P:phrase(A,B), X:list(A), Y:list(B))// is nondet
 seqmap_with_sep(+S:phrase, +P:phrase(A,B,C), X:list(A), Y:list(B), Z:list(C))// is nondet
As seqmap//2.. but inserting the separator phrase S between each call to P. NB: Fails for empty lists.
See also
- seqmap//2
 seqmap_ints(+P:phrase(integer), +I:integer, +J:integer)// is nondet
Equivalent to seqmap(P) applied to the list of integers from I to J inclusive.
See also
- seqmap//2.
 seqmap_args(+P:phrase(integer), +I:integer, +J:integer, X:term)// is nondet
 seqmap_args(+P:phrase(integer), +I:integer, +J:integer, X:term, Y:term)// is nondet
 seqmap_args(+P:phrase(integer), +I:integer, +J:integer, X:term, Y:term, Z:term)// is nondet
Like seqmap//N, but applied to the arguments of term X, Y and Z, from the I th to the J th inclusive.
See also
- seqmap//2.
 setof(Template:X, Phrase:phrase(S), Results:list(X), S1:S, S2:S) is nondet
 findall(Template:X, Phrase:phrase(S), Results:list(X), S1:S, S2:S) is nondet
 out(?X)// is det
Equivalent to [X]. prepends X to the difference list represented by the DCG state variables.
 list(?L)// is nondet
Matches or outputs a sequence of nonterminals.

Undocumented predicates

The following predicates are exported, but not or incorrectly documented.

 \+(Arg1, Arg2, Arg3)
 forall(Arg1, Arg2, Arg3, Arg4)
 if(Arg1, Arg2, Arg3, Arg4)
 do_then_call(Arg1, Arg2, Arg3, Arg4, Arg5)
 do_then_call(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 do_then_call(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 lift(Arg1, Arg2, Arg3)
 lift(Arg1, Arg2, Arg3, Arg4)
 lift(Arg1, Arg2, Arg3, Arg4, Arg5)
 parmap(Arg1, Arg2, Arg3, Arg4)
 parmap(Arg1, Arg2, Arg3, Arg4, Arg5)
 parmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 parmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 parmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)
 seqmap(Arg1, Arg2, Arg3, Arg4, Arg5)
 seqmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 seqmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 seqmap(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)
 seqmap_n(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 seqmap_n(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 seqmap_with_sep(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 seqmap_with_sep(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 seqmap_args(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 seqmap_args(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)