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
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.