What would be the best way to define a phrase that can describe an adverb in either one of two ways?
Could you just say:
adverb_phrase(N,adv(N,Adv)) --> Way 1.
adverb_phrase(N,adv(N,Adv)) --> Way 2.
I've tried doing this but I get variables (like _G12345
) in the output, which doesn't look right.
Yes, what you show is definitely a valid way to state alternatives in DCGs.
There are other options too. Here are some:
This is your version, only extended to a somewhat more complete example:
adverb_phrase(N, adv(N,Adv)) --> adv1(Adv). adverb_phrase(N, adv(N,Adv)) --> adv2(Adv). adv1(likely) --> []. adv2(happily) --> [].
Example query and answer:
?- phrase(adverb_phrase(N,A), Ls). A = adv(N, likely), Ls = [] ; A = adv(N, happily), Ls = [].
Two solutions are found on backtracking. The variable N
also occurs in the query. I do not know why you introduced it, and if you do not need it, you can simply omit it.
Using different rules to denote alternatives is straight-forward. Note that you can refactor the code to make it more compact:
adverb_phrase(N, adv(N,Adv)) --> adv(Adv). adv(likely) --> []. adv(happily) --> [].
In this case, I have simply used the same nonterminal to denote the alternatives.
('|')//2
Note that there are also other ways to denote alternatives. An elegant way is to use ('|')//2
, in analogy to how alternatives are often indicated in other formalisms.
For example, you can write your initial example as:
adverb_phrase(N, adv(N,Adv)) --> adv1(Adv) | adv2(Adv). adv1(likely) --> []. adv2(happily) --> [].
Instead of ('|')//2
, you can also use (;)//2
if you want to, in analogy to plain Prolog.
The shown variants yield exactly the same answers. The version you choose depends on several factors, for example: Are you using the DCG more in the "grammar" or more in the "monad" sense.
For your specific case, version 2 seems a good fit from a first impression.
Note that neither of these options is an "or statement". We call these nonterminals!