Eliminating left recursion for a specific grammar - left-recursion

I've looked through a million examples/tutorials but I still can't manage to eliminate left recursion for this grammar:
S --> C
C --> Dc|c
D --> Cd|d
Any ideas?

First make the indirect recursion to an immediate one via eliminating D. You only have two nonterminals, so it can be done.
S --> C
C --> Cdc|dc|c
Then you can work on making it tail-recursive:
S --> C
C --> dcC'|cC'
C'--> dcC'
The trick in the second part is to take all terminals from derived from C (here, dc and c) and give them a tail (C --> dcC'|cC'). This dc and c is the same terminal set that came after Cdc in the first rule set. Then you create a rule for the new nonterminal (the tail) and put it after the terminals from the first rule (ie. this dc comes from Cdc).
To make it clearer:
S --> C
C --> Db|f
D --> Ca|c
-->
S --> C
C --> Cab|cb|f
-->
S --> C
C --> cbC'|fC'
C'--> abC'

Related

Why do I need to duplicate my Prolog predicates in order to make my program work?

I am using SICStus Prolog 4.0.8 to write a program that parses a sentence in English and returns the syntactic tree, as well as a yes/no on whether the sentence is correct according to the programmed grammar. Here is an example (sentence is Larry and Carol meet their older neighbors Paul and Lillian):
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
If I run the code like this, it complains that np2/3 is not defined, but if I put the numbers before the brackets, then it complains np/3 is not defined. My only solution is to put both predicates in, like this:
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
np1(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np2(np2(D, A, N)) --> det(D), adj(A), cn(N).
vp1(vp1(V, A)) --> tv(V), app(A).
Then it compiles and executes successfully. What's the cause of this behavior?
In the first version of your code, the clause
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
defines the predicate np/3 (and calls the predicate pn/3). However, the clause
app(app(N1, N2)) --> np2(N1), np1(N2).
calls predicates np2/3 and np1/3, which are not defined. That's the cause of the runtime error.
In the second version of your code, the predicates np2/3 and np1/3 are also defined and, therefore, there is no error.
What's the problem? I think you are confusing np/3 and pn/3 (which are predicates) with np1/3 and np2/3 (which are terms representing syntax tree nodes).
np( np1(N1, C, N2) ) --> pn(N1), conj(C), pn(N2).
^ ^ ^
| | |
| | +--- predicate being called (must be defined)
| |
| +----------------------- term representing a syntax tree node (this is not a predicate)
|
+---------------------------- predicate being defined

How to add constraint to a list that is generated by a definite clause grammar?

I'm trying to use definite clause grammars in prolog to accept strings of the form u,2,v where u and are strings of zeroes and ones. There is a constraint whereby the number of zeroes in 'u' must equal the number of ones in 'v'.
I can get the interpreter to accept strings of u,2,v but I'm having trouble adding the constraints.
s--> t,
{t(Input,[]),
find_zeroes(Input,X),length(X,Z),
reverse(Input,RevInput),find_ones(RevInput,Y),length(Y,Z)}.
t --> [2].
t --> l,[2],r.
l --> [X],{member(X,[0,1])}.
l --> [X],l,{member(X,[0,1])}.
r --> [Y],{member(Y,[0,1])}.
r --> [Y],r,{member(Y,[0,1])}.
accfindzeroes([H|T],Acc,Result):- H = 0, accfindzeroes(T,[H|Acc],Result).
accfindzeroes([H|T],Acc,Result):- H \= 0, accfindzeroes(T,Acc,Result).
accfindzeroes([2|_],Acc,Acc).
find_zeroes(List,Result):-accfindzeroes(List,[],Result).
accfindones([H|T],Acc,Result):- H = 1, accfindones(T,[H|Acc],Result).
accfindones([H|T],Acc,Result):- H \= 1, accfindones(T,Acc,Result).
accfindones([2|_],Acc,Acc).
find_ones(List,Result):-accfindones(List,[],Result).
For example:
?- t([0,1,1,2,1,0,0],[]).
True.
As required, but,
?- s([0,1,1,2,1,0,0],[]).
Loops infinitely...
I'm pretty sure the problem is in the second line but I don't know how to rectify it. I think the problem is 't' isn't outputting a list before attempting to resolve the constraints so it doesn't work but as I said I'm a bit stuck.
It seems to be a duplicate question, but I have already written the code.
t --> [2].
t --> l(N),[2],r(N).
l(0) --> [].
l(N) --> [0],l(N0), { N is N0 + 1 }.
l(N) --> [1],l(N).
r(0) --> [].
r(N) --> [0],r(N).
r(N) --> [1],r(N0), { N is N0 + 1 }.
Your problem is that the call t(Input,[]) just generates longer and longer sequences, without any connection to your input.

right linear context free grammar

I've a problem. I have to write right linear context free grammar with alphapet={0,1} where the numbers of 0 will be even and the numbers od 1 will be odd. I tried write sth. but it's doesn't work.
s --> [1],a.
s --> [0],b.
a --> [].
a --> [1],c.
a --> [0],b.
c --> [1],k.
c --> [0],b.
b --> [0],k.
b --> [1],d.
d --> [1],b.
d --> [0],c.
k --> [].
k --> s.
Grammar should accept even amount of 0s and odd amount of 1s. Grammar context free is right linear when A->wB or A->w where w is any word under our alphabet and A,B is no terminals
How about
s --> [1],oddOnesEvenZeros.
s --> [0],oddZerosEvenOnes.
oddOnesEvenZeros--> [].
oddOnesEvenZeros--> [1],s.
oddOnesEvenZeros--> [0],oddZerosOddOnes.
oddZerosEvenOnes--> [1],oddZerosOddOnes.
oddZerosEvenOnes--> [0],s.
oddZerosOddOnes --> [1],oddZerosEvenOnes.
oddZerosOddOnes --> [0],oddOnesEvenZeros.
The grammar is regular because you don't have to remember the parts you have already passed, you can only remember current state of each, i.e. four different states, from which one (odd ones, even zeros) is accepting. As a regular grammar, it is right linear CFG as well.
Maybe something like this?
s --> [].
s --> even_zeros, s.
s --> odd_ones, s.
even_zeros([0,0], []).
even_zeros, [X] --> [0,0,X], {X \== 0}.
even_zeros --> [0,0], even_zeros.
odd_ones([1], []).
odd_ones, [X] --> [1,X], {X \== 1}.
odd_ones --> [1,1], odd_ones.
I've interpreted the question as asking for a grammar of sequences of 0s and 1s, where the number of consecutive 0s is always even and the number of consecutive 1s is always odd.

Right linear context free grammar with even difference of 0's and 1's

I'm trying to write a right linear context free grammar, in which the difference between numbers of 0's and 1's should be even. For example:
010001 = 4 - 2 = 2 (even)
I had a similar problem. Maybe it will help! I'm trying to write it on prolog. I did other 10 exercises but this is too difficult for me. Any ideas on how to do it?
my code
s --> [].
s --> [1],a.
s --> [0],b.
a --> [1],s.
a --> [0],c.
b --> [1],c.
b --> [0],s.
c --> [].
c --> [1],b.
c --> [0],a.
It's work for many cases but I'm not sure if it is well.
The problem can be greatly simplified with a little math.
Let a be number of 0, b - number of 1, n - length of a word. We want abs(a - b) to be even.
Do the math:
a + b = n
b = n - a
a - b = a - n + a = 2*a - n
2*a is always even, so abs(a - b) is even iff n is even.
So the task is really just to check if the length of the word is even.
Solution:
s --> [].
s --> digit, digit, s.
digit --> [0].
digit --> [1].

Computing the Follow Set

Ok, I've understood how to compute the Follow_k(N) set (N is a nonterminal): for every production rule of the form A -> aBc you add First_k(First_k(c)Follow_k(A)) to Follow_k(B) (a, c are any group of terminals and nonterminals, or even lambda). ...and you repeat this until there's nothing left to add.
But what happends for production rules like: S -> ABCD (A, B, C, D are all nonterminals)?
Should I
add First_k(First_k(BCD)Follow_k(S)) to Follow_k(A) or
add First_k(First_k(CD)Follow_k(S)) to Follow_k(B) or
add First_k(First_k(D)Follow_k(S)) to Follow_k(C) or
add First_k(First_k(lambda)Follow_k(S)) to Follow_k(D) or
do all of the above?
UPDATE:
Let's take the following grammar for example:
S -> ABC
A -> a
B -> b
C -> c
Intuitively, Follow_1(S) = {} because nothing follows after S
Follow_1(A) = {b} because b follows after A,
Follow_1(B) = {c} because c follows after B,
Follow_1(C) = {} because nothing follows after C.
In order to get this result using the algorithm you must consider all cases for S -> ABC.
But my judgement or example may not be right so the question still remains open...
If you run into trouble on other grammar problems like this, give this online first, follow, & predict set finder a shot. It's automatic and you can compare answers to its output to get a feel for how to work through these.
But what happens for production rules like: S -> ABCD (A, B, C, D are all nonterminals)?
Here are the rules for finding follow sets.
First put $ (the end of input marker) in Follow(S) (S is the start symbol)
If there is a production A → aBb, (where a can be a whole string) then everything in FIRST(b) except for ε is placed in FOLLOW(B).
If there is a production A → aB, then everything in FOLLOW(A) is in FOLLOW(B)
If there is production A → aBb, where FIRST(b) contains ε, then everything in FOLLOW(A) is in FOLLOW(B)
Let's use your example grammar:
S -> ABC
A -> a
B -> b
C -> c
Rule 1 says that follow(S) contains $.
Rule 2 gives us: follow(A) contains first(B); also, follow(B) contains first(C).
Rule 3 says that follow(C) contains follow (S).
None of your productions are nullable, so we don't care about rule #4. A symbol is nullable if it derives ε or if it derives a nullable non-terminal symbol.
Nullability's transitivity can trip people up. Consider this grammar:
S -> A
A -> B
B -> ε
Since B derives ε, B's nullable. Since A derives B, which derives ε, A's nullable too. S derives A, which derives B, which derives ε, so S is nullable as well.
Granted, you didn't bring that up, but it's a common source of confusion in compiler courses, so I figured I'd lay it out.
Also, if you need some sample grammars to work through, http://faculty.stedwards.edu/laurab/cosc4342/g1answers.txt might be handy.

Resources