Search code examples
prologdcg

definite clause grammar (dcg) Prolog (homework)


i tried to write a predicate and N={Expression,Number,Digit,Operator,Variable}

T={1,2,3,+,-,*,(,),X,Y,Z} and S is expression and program p defines as

Expression-->Number
**Expression-->(Expression) Operator (Expression)**
Number-->Digit
**Number --> Digit Number**
Digit-->1
Digit-->2
Digit-->3
Operator-->+
Operator-->-
Operator-->*
Variable-->X
Variable-->Y
Variable-->Z

I think that i implemented many parts however could not implement bold parts!!

my prolog code that describes the terminals by depending program P:

 expression(S,S).
    expression(S,R):-number(S,R).
    expression(S,R):-expression(S,R),-operator(S,['('|S]),expression(S,[')'|R]).
    expression(S,R):-operator(S,[','|S1]),expression(S1,R).
    expression(S,R):-variable(S,[','|S1]),expression(S1,R).
    number(S,R):-digit(S,R).
    digit(['1'|R],R).
    digit(['2'|R],R).
    digit(['3'|R],R).
    operator(['+'|R],R).
    operator(['-'|R],R).
    operator(['*'|R],R).
    variable(['X'|R],R).
    variable(['Y'|R],R).
    variable(['Z'|R],R).

Please help me.


Solution

  • Here is probably the you meant:

    :- set_prolog_flag(double_quotes, chars).
    
    expression --> number.
    expression --> variable.
    expression --> "(", expression, operator, expression, ")".
    
    number --> digit.
    number --> digit, number.
    
    digit --> "1".
    digit --> "2".
    digit --> "3".
    
    operator --> "+"|"-"|"*".  % more compact notation
    variable --> "X"|"Y"|"Z".
    

    Use it like so to generate all sentences ordered by length:

    ?- length(L, N), phrase(expression, L).
       L = ['1'], N = 1
    ;  L = ['2'], N = 1
    ;  L = ['3'], N = 1
    ;  L = ['X'], N = 1
    ;  L = ['Y'], N = 1
    ;  L = ['Z'], N = 1
    ;  L = ['1', '1'], N = 2
    ;  L = ['1', '2'], N = 2
    ;  ... .
    

    And to get most compact and readable answers see this for more. That is, download the module below:

    ?- use_module(double_quotes).
    ?- length(L, N), phrase(expression, L).
       L = "1", N = 1
    ;  L = "2", N = 1
    ;  L = "3", N = 1
    ;  L = "X", N = 1
    ;  L = "Y", N = 1
    ;  L = "Z", N = 1
    ;  L = "11", N = 2
    ;  L = "12", N = 2
    ;  ... .
    

    To see how the DCG is implemented, say listing for each non-terminal. E.g.:

    ?- listing(expression).
    expression(A, B) :-
            number(A, B).
    expression(A, B) :-
            variable(A, B).
    expression(['('|A], E) :-
            expression(A, B),
            operator(B, C),
            expression(C, D),
            D=[')'|E].