Question

I need to implement some rules by Prolog

ex:

S ---> A,[b],{c}.

Where:

[b] could happen once or none like 0 or 1 time

{c} could happen 0,1,2,...times

How can i write it?

Edit:

I used this:

:- op(700,xfx,--->).
s ---> [vp].
s ---> [vp,conj,vp].
s ---> [vp,conj,np].
vp ---> [feal_amr],
        ([mfoal_beh];[]),
        ([mfoal_beh];[]),
        ([bdl];[]),
        [sefa_optional],
        ([hal];[]),
        ([shbh_gomla];[]),
        ([mfoal_motlk];[]).

It gives me an error "Full stop in clause-body? Cannot redefine ,/2"

in the comma in this line "vp ---> [feal_amr], ..."

Edit

I use "--->" because i have this

parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
        Category ---> RHS,
        matches(RHS,String,Reststring,Subtrees).

And "-->" gives an error with the operator ":-"?!!

this is my code for an Arabic Parser Code

I'm sorry for inconvenience but i am not an expert in Prolog

Was it helpful?

Solution

from your description

s --> [a], ([b] ; []), c_1.
c_1 --> [c], c_1 ; [].

some test pattern:

?- phrase(s, [a,b,c,c,c]).
true

?- phrase(s, [a]).
true

edit

about your code: you should use -->. Why you declare ---> (and not define it) ? That way you should write your own analyzer, you're not using DCG.

Note that [vp,conj,vp] it's a list of terminals,

Not sure about feal_amr,mfoal_beh, etc etc, but vp it's surely a nonterminal (it's rewritten).

Then I think you should write

s --> vp.
s --> vp,conj,vp.
s --> vp,conj,np.

vp -->
  [feal_amr],
  ([mfoal_beh];[]),
  ([mfoal_beh];[]),
  ([bdl];[]),
  [sefa_optional],
  ([hal];[]),
  ([shbh_gomla];[]),
  ([mfoal_motlk];[]).

% I hypotesize it's a comma.
conj --> [','].

edit as noted in comments, you are not using DCG, but your own interpreter. I tested it with a minimal example

:- op(700,xfx,--->).

s ---> [name,verb,names].

names ---> [name, conj, names].
names ---> [name].
names ---> [].

lex(anne, name).
lex(bob, name).
lex(charlie, name).

lex(call, verb).
lex(and, conj).

parse_topdown(Category,[Word|Reststring],Reststring,[Category,Word]) :-
        lex(Word,Category).

parse_topdown(Category,String,Reststring,[Category|Subtrees]) :-
        Category ---> RHS,
        matches(RHS,String,Reststring,Subtrees).

matches([],String,String,[]).
matches([Category|Categories],String,RestString,[Subtree|Subtrees]) :-
        parse_topdown(Category,String,String1,Subtree),
        matches(Categories,String1,RestString,Subtrees).

and this program accepts 0,1, or more names:

?- parse_topdown(s,[anne,call,bob,and,charlie],R,P).
R = [],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names|...]]] ;
R = [charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob], [conj, and], [names]]] ;
R = [and, charlie],
P = [s, [name, anne], [verb, call], [names, [name, bob]]] ;
R = [bob, and, charlie],
P = [s, [name, anne], [verb, call], [names]] ;
false.

Note I leave R free, to examine partial matches. Coming back to your original question, you can see how the nonterminal names accepts 0,1,or many (separed by and) values.

Note that such interpreter will be very slow on any substantial input. I'd advise you to rewrite your grammar using DCG.

OTHER TIPS

First, you probably want to lower-case S and A; Prolog uses initial caps for variable names.

One way to allow 'b' to occur once or not at all is to write something like this:

s --> a, b_optional, {c}.

b_optional --> [b].
b_optional --> [].

There is also syntax for writing the two rules for b_optional as a single rule, if you prefer; consult the chapter on definite clause grammars in your favorite Prolog text.

I don't know what you mean by c happening 0, 1, 2, ... times, so I don't think I can help you there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top