Very basic dcg prolog syntax

2019-02-25 08:18发布

问题:

I am trying to understand prolog and definite clause grammar but I am having a very hard time understanding both of them.

I am really trying to understand how to use the dcg syntax...

Here I have two examples:

The first is actually the code from another question on this forum but with an additional question:

The code looked like this:

s --> first, operator, second.
first --> [X].
operator --> ['+'].
second --> [X].

And when Prolog is asked about this, it returns true/false but I can't for the life of me figure out how to actually modify this to "bind" the value so if asked s(X, [2,+,2],[]). it would return the value of first, so instead of returning true it'd say X = 2

Anyway back to the actual question. I have a few rules in normal prolog and this is one of them; it doesn't actually do anything and was merely made up as an example.

do(X, Y, [H|T], Sum):-
    H == 1, %check if H is 1
    X = H,
    Y = T,
    Additional is H+5,
    Sum is Additional+Additional.

Basically, I am asking if someone could translate this to DCG so that I could try and understand the basic syntax of DCG! I've tried reading some tutorials but I feel like I haven't gotten any wiser...

回答1:

DCG: foo(A1, A2, A3, ... , An) --> bar.

Prolog: foo(A1, A2, A3, ... , An, X, Y) :- bar(X,Y)

So, s should be changed to:

s(X) --> first(X), operator, second.
first(X) --> [X].
operator --> ['+'].
second --> [X].

Of course, it might be better to return the actual result; to do this you should encapsulate prolog code in the DCG clause which is done with {}:

s(Z) --> first(X), operator, second(Y), {Z is X+Y}.
first(X) --> [X].
operator --> ['+'].
second(X) --> [X].

(naturally, if you have more operators, the prolog code won't be that simple).

Regarding the do/4 predicate, it should be something like this:

do(X,Y,[H|T],Sum) -->
   {H == 1, %check if H is 1
    X = H,
    Y = T,
    Additional is H+5,
    Sum is Additional+Additional}.

but I don't see why you would want that.

One last tip: it's recommended to use phrase/3 instead of adding the last two arguments in a DCG predicate.



回答2:

it's not easy to translate do/4 to DCG in meaningful way. I've removed arguments that 'copy' the hidden arguments of the DCG.

do(Sum) -->
    [1],  %check if H is 1
    {  % braces allow 'normal' Prolog code (but we have no access to 'hidden' arguments)
    Additional is H+5,
    Sum is Additional+Additional
    }.

edit sorry I forgot H in Additional is H+5,, should read Additional is 1+5,...



标签: prolog dcg