right linear context free grammar - prolog

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.

Related

DCG : zero-or-more, zero-or-one , one-or-more occurrences?

In DCG how do you implement : zero-or-more, zero-or-one , one-or-more occurrences ?
I'm talking about the following in pseudo code :
sentence --> word+
float --> int+, ['.'], int+
nilORa --> a?
nilORaaaa --> a*
You use the or-nondeterminism offered by the clause set of a predicate (or, in this case, the set of DCG productions for the same DCG "nonterminal" - the DCG production is an alternative notation for a Horn clause)
Move the production that should be performed first to the top. For example, to collects at least one word, but possibly more, greedily:
sentence --> word, sentence.
sentence --> word.
Depending on how much determinism is in the grammar, you can even cut:
sentence --> word, !, sentence.
sentence --> word.
Same with a float. digits is at least one digit. There already is a definition for digit in the library I think:
float --> digits, ['.'], digits.
digits --> digit, digits.
digits --> digit.
nilORa is an a -- or possibly nothing:
nilORa --> a.
nilORa --> [].
nilORaaaa is an a followed by nilORaaaa -- or possibly nothing:
nilORaaaa --> a, nilORaaaa.
nilORaaaa --> [].
You should also be able to deploy ; I think:
nilORaaaa --> (a, nilORaaa) ; [].

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

Problems with DCG (Prolog)

I am trying to work out this simple DCG assignment (Prolog) for my course. The prblem is about creating a DCG. I have already defined a Universe of Discourse in my code. But this question is a bit misleading to me. According to what I've read and know, using my own notes and this Learn Prolog Now! - LINK: http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse29
One can construct a DCG with (a^nb^nc^n). Where a b and c are normal letters and n is the number the letter is to be multiplied with. However, my question is like this.
"Design and implement a DCG to recognize (or generate) the language 0n1n0n."
Can somebody please help me out here? What is exactly wanted by the question?
With regards to one of the answers, I have tried the following code with no luck.
s --> [].
s(M) --> a(M),b(M),c(M).
a --> [].
a(New) --> [0], a(Cnt),{New is Cnt+1}.
b --> [].
b(New) --> [1], b(Cnt),{New is Cnt+1}.
c --> [].
c(New) --> [0], c(Cnt),{New is Cnt+1}.
count(T, N) --> [0,1,0], count(T, M), {N is M+1}.
count(_, 0) --> [].
DCGs are a sublanguage hosted in Prolog, then it's easy to count occurrences of a terminal T.
count(T, N) --> [T], count(T, M), {N is M+1}.
count(_, 0) --> [].
?- phrase(count(a, C), [a,a,a]).
C = 3 ;
false.
Of course, you should find this can solve your question easily.
EDIT: I missed the generation part. count//2 will not work for generation, because of builtin arithmetic. Using the successors notation the code can work as a generator too:
count(T, s(N)) --> [T], count(T, N).
count(_, 0) --> [].
I think "0n1n0n" means "0n1n0n", i.e. some number of zeros, followed by same number of ones and followed by same number of zeros again.

Define a dcg for palindromes over the alphabet {a,b} of 2 symbols a and b such that the number of a's is one less than the number of b's

I am trying to define a palindrome where the number of a's is one less than the number of b's.
I cant seem to figure out how to write it properly
please-->palindromes.
palindromes-->[].
palindromes-->[a].
palindromes-->[b].
palindromes--> [b],palindromes,[b].
Think about this: where the surplus 'b' could stay ? In a palindrome, there is only one such place. Then change the symmetric definition, that in BNF (you already know as translate to DCG) would read
S :: P
P :: a P a | b P b | {epsilon}
You're on the right track, you just need a way to deal with the difference in counts. You can do this by adding a numeric argument to your palindromes grammar term.
First I'll define an ordinary Prolog rule implementing "B is two more than A":
plus2(A,B) :- number(A), !, B is A+2.
plus2(A,B) :- number(B), !, A is B-2.
plus2(A,B) :- var(A), var(B), throw(error(instantiation_error,plus2/2)).
Then we'll say palindromes(Diff) means any palindrome on the given alphabet where the number of b letters minus the number of a letters is Diff. For the base cases, you know Diff exactly:
palindromes(0) --> [].
palindromes(-1) --> [a].
palindromes(1) --> [b].
For the recursive grammar rules, we can use a code block in {braces} to check the plus2 predicate:
palindromes(DiffOuter) --> [b], palindromes(DiffInner), [b],
{ plus2(DiffInner, DiffOuter) }.
palindromes(DiffOuter) --> [a], palindromes(DiffInner), [a],
{ plus2(DiffOuter, DiffInner) }.
To finish off, the top-level grammar rule is simply
please --> palindromes(1).

Resources