Prolog DCG definition with additional arguments

I am trying to define Prolog DCG for a set of rows 0 ^ N 1 ^ M 2 ^ N + M of length 2N + 2M for N, M> = 0 using additional arguments. An example of a valid string would be "011222" but not "012".

I used the following code to create this DCG.

s --> a(N), b(M), c(N), c(M).

a(0) --> [].
a(succ(X)) --> [0], a(X).

b(0) --> [].
b(succ(X)) --> [1], b(X).

c(0) --> [].
c(succ(X)) --> [2], c(X).

      

When I run the request

s([0,1,1,2,2,2], []).

      

Prolog returns true as expected.

However, when I run

s(X, []).

      

Prolog returns the following:

X = []
X = [1,2]
X = [1,1,2,2]
X = [1,1,1,2,2,2]

      

These are invalid strings. I think this might be due to the fact that N and M are decremented by predicate c before the prologue executes predicates a and b. This is true? How can this be solved?

Edit: I've tried modifying the s version for this:

s --> a(N), b(M), c(NplusM), {NplusM is N + M}.

      

but this results in an error when executing queries.

+3


source to share


2 answers


You are using succ / 2 incorrectly, perhaps because you expect Prolog to evaluate functions in head templates. This is not true. Then try replacing your rules with

a(0) --> [].
a(Y) --> {succ(X,Y)}, [0], a(X).

      

etc.

since succ / 2 needs at least one argument created for an integer, we could put N, M in the DCG record, or using CLP (FD):



:- use_module(library(clpfd)).

s --> a(N), b(M), c(N), c(M).

a(0) --> [].
a(Y) --> {Y #= X-1}, [0], a(X).

b(0) --> [].
b(Y) --> {Y #= X-1}, [1], b(X).

c(0) --> [].
c(Y) --> {Y #= X-1}, [2], c(X).

      

but the length of the list must be specified. for example

?- length(L,_),phrase(s,L).
L = [] ;
L = [1, 2] ;
L = [0, 2] ;
L = [1, 1, 2, 2] ;
L = [0, 1, 2, 2] ;
L = [0, 0, 2, 2] ;
...

      

+1


source


IMO the answers you get are correct!

I renamed your grammar from s

to aN_bM_cNM

and added two additional arguments, one for N

and one for M

. Also, I renamed succ

to s

:

aN_bM_cNM (N, M) -> n_reps (N, 0), n_reps (M, 1), n_reps (N, 2), n_reps (M, 2).

n_reps (0, _) -> [].
n_reps (s (N), E) -> [E], n_reps (N, E).

Now run the query that @CapelliC gave. The goal length(Xs, _)

provides a fair listing of an infinite set of solutions aN_bM_cNM//2

:



? - length (Xs, _), phrase (aN_bM_cNM (N, M), Xs).
(Xs = [], N = 0, M = 0
; Xs = [1,2], N = 0, M = s (0)
; Xs = [0.2], N = s (0), M = 0
; Xs = [1,1,2,2], N = 0, M = s (s (0))
; Xs = [0,1,2,2], N = s (0), M = s (0)
; Xs = [0,0,2,2], N = s (s (0)), M = 0
; Xs = [1,1,1,2,2,2], N = 0, M = s (s (s (0)))
; Xs = [0,1,1,2,2,2], N = s (0), M = s (s (0))
; Xs = [0,0,1,2,2,2], N = s (s (0)), M = s (0)
; Xs = [0,0,0,2,2,2], N = s (s (s (0))), M = 0
; Xs = [1,1,1,1,2,2,2,2], N = 0, M = s (s (s (s (0))))
...

To raise the bottom border N

or M

, just provide an additional shape target X = s(s(_))

(for a minimum value of 2). In the next request, the values N

and M

must be greater 0

:

? - N = s (_), M = s (_), length (Xs, _), phrase (aN_bM_cNM (N, M), Xs).
(N = s (0), M = s (0), Xs = [0,1,2,2]
; N = s (0), M = s (s (0)), Xs = [0,1,1,2,2,2]
; N = s (s (0)), M = s (0), Xs = [0,0,1,2,2,2]
; N = s (0), M = s (s (s (0))), Xs = [0,1,1,1,2,2,2,2]
...
+1


source







All Articles