Is there a way to create a type 3 grammar for this language? - formal-languages

I'm trying to find a grammar of the highest type possible for this language:
L={0^2n 1^(n-1)|n>=1}
I only managed to do this:
S->00X
X->00X1|λ
Which is not type 3. I can't seem to figure out how to get it to type 3 (if that's even possible).

You can't do it, because L is not a regular language.
Assume that L is regular. Let w = 0^(2p)1^(p-1) for some integer p>=1, so that |w| > p. Further, consider the strings x, y, and z such that w = xyz with |xy| <= p, which means both x and y are sequences of 0s (since p < 2p). By the pumping lemma, any string of the form xy^nz is also in L, but that means we can increase the number of 0s without increasing the number of 1s found in z. Thus, our assumption that L is regular must be false.

Related

How to use Wolfram Alpha to find a set of solutions that hold for any variables in the domain

Say that x and y are real numbers and y > 0. And say that I want to find for which values of A do (A + x + y > 0) and (A + x - y > 0) always hold, as long as x, y are in the domain.
How would I specify that on Wolfram Alpha? (Note: obviously these equations have no solution, but I just used it as an example.)
Or, if not on Wolfram, what software/website could I use?
I tried to write: solve for A: [input my first equation], y>0
but that didn't work, as it only gave integer solutions for when A, x, and y vary, instead of finding values of A such that it always holds no matter what x, y are.
https://www.wolframalpha.com/input?i=%28A+%2B+x+%2B+y+%3E+0%29+and+%28A+%2B+x+-+y+%3E+0%29+
[x>-A, -A - x<y<A + x]

Defining a mathematical language in prolog

So I have this mathematical language, it goes like this:
E -> number
[+,E,E,E] //e.g. [+,1,2,3] is 1+2+3 %we can put 2 to infinite Es here.
[-,E,E,E] //e.g. [-,1,2,3] is 1-2-3 %we can put 2 to infinite Es here.
[*,E,E,E] //e.g. [*,1,2,3] is 1*2*3 %we can put 2 to infinite Es here.
[^,E,E] //e.g. [^,2,3] is 2^3
[sin,E] //e.g. [sin,0] is sin 0
[cos,E] //e.g. [cos,0] is cos 0
and I want to write the set of rules that finds the numeric value of a mathematical expression written by this language in prolog.
I first wrote a function called "check", it checks to see if the list is written in a right way according to the language we have :
check1([]).
check1([L|Ls]):- number(L),check1(Ls).
check([L|Ls]):-atom(L),check1(Ls).
now I need to write the function "evaluate" that takes a list that is an expression written by this language, and a variable that is the numeric value corresponding to this language.
example:
?-evaluate([*,1,[^,2,2],[*,2,[+,[sin,0],5]]]],N) -> N = 40
so I wrote this:
sum([],0).
sum([L|Ls],N):- not(is_list(L)),sum(Ls,No),N is No + L.
min([],0).
min([L|Ls],N):-not(is_list(L)), min(Ls,No),N is No - L.
pro([],0).
pro([X],[X]).
pro([L|Ls],N):-not(is_list(L)), pro(Ls,No), N is No * L.
pow([L|Ls],N):-not(is_list(L)), N is L ^ Ls.
sin_(L,N):-not(is_list(L)), N is sin(L).
cos_(L,N):-not(is_list(L)), N is cos(L).
d([],0).
d([L|Ls],N):- L == '+' ,sum(Ls,N);
L == '-',min(Ls,N);
L == '*',pro(Ls,N);
L == '^',pow(Ls,N);
L == 'sin',sin_(Ls,N);
L == 'cos',cos_(Ls,N).
evaluate([],0).
evaluate([L|Ls],N):-
is_list(L) , check(L) , d(L,N),L is N,evaluate(Ls,N);
is_list(L), not(check(L)) , evaluate(Ls,N);
not(is_list(L)),not(is_list(Ls)),check([L|Ls]),d([L|Ls],N),
L is N,evaluate(Ls,N);
is_list(Ls),evaluate(Ls,N).
and it's working for just a list and returning the right answer , but not for multiple lists inside the main list, how should my code be?
The specification you work with looks like a production rule that describes that E (presumably short for Expression) might be a number or one of the 6 specified operations. That is the empty list [] is not an expression. So the fact
evaluate([],0).
should not be in your code. Your predicate sum/2 almost works the way you wrote it, except for the empty list and a list with a single element, that are not valid inputs according to your specification. But the predicates min/2 and pro/2 are not correct. Consider the following examples:
?- sum([1,2,3],X).
X = 6 % <- correct
?- sum([1],X).
X = 1 % <- incorrect
?- sum([],X).
X = 0 % <- incorrect
?- min([1,2,3],X).
X = -6 % <- incorrect
?- pro([1,2,3],X).
X = 6 ? ; % <- correct
X = 0 % <- incorrect
Mathematically speaking, addition and multiplication are associative but subtraction is not. In programming languages all three of these operations are usually left associative (see e.g. Operator associativity) to yield the mathematically correct result. That is, the sequence of subtractions in the above query would be calculated:
1-2-3 = (1-2)-3 = -4
The way you define a sequence of these operations resembles the following calculation:
[A,B,C]: ((0 op C) op B) op A
That works out fine for addition:
[1,2,3]: ((0 + 3) + 2) + 1 = 6
But it doesn't for subtraction:
[1,2,3]: ((0 - 3) - 2) - 1 = -6
And it is responsible for the second, incorrect solution when multiplying:
[1,2,3]: ((0 * 3) * 2) * 1 = 0
There are also some other issues with your code (see e.g. #lurker's comments), however, I won't go into further detail on that. Instead, I suggest a predicate that adheres closely to the specifying production rule. Since the grammar is describing expressions and you want to know the corresponding values, let's call it expr_val/2. Now let's describe top-down what an expression can be: It can be a number:
expr_val(X,X) :-
number(X).
It can be an arbitrarily long sequence of additions or subtractions or multiplications respectively. For the reasons above all three sequences should be evaluated in a left associative way. So it's tempting to use one rule for all of them:
expr_val([Op|Es],V) :-
sequenceoperator(Op), % Op is one of the 3 operations
exprseq_op_val(Es,Op,V). % V is the result of a sequence of Ops
The power function is given as a list with three elements, the first being ^ and the others being expressions. So that rule is pretty straightforward:
expr_val([^,E1,E2],V) :-
expr_val(E1,V1),
expr_val(E2,V2),
V is V1^V2.
The expressions for sine and cosine are both lists with two elements, the first being sin or cos and the second being an expression. Note that the argument of sin and cos is the angle in radians. If the second argument of the list yields the angle in radians you can use sin/1 and cos/2 as you did in your code. However, if you get the angle in degrees, you need to convert it to radians first. I include the latter case as an example, use the one that fits your application.
expr_val([sin,E],V) :-
expr_val(E,V1),
V is sin(V1*pi/180). % radians = degrees*pi/180
expr_val([cos,E],V) :-
expr_val(E,V1),
V is cos(V1*pi/180). % radians = degrees*pi/180
For the second rule of expr_val/2 you need to define the three possible sequence operators:
sequenceoperator(+).
sequenceoperator(-).
sequenceoperator(*).
And subsequently the predicate exprseq_op_val/3. As the leading operator has already been removed from the list in expr_val/2, the list has to have at least two elements according to your specification. In order to evaluate the sequence in a left associative way the value of the head of the list is passed as an accumulator to another predicate exprseq_op_val_/4
exprseq_op_val([E1,E2|Es],Op,V) :-
expr_val(E1,V1),
exprseq_op_val_([E2|Es],Op,V,V1).
that is describing the actual evaluation. There are basically two cases: If the list is empty then, regardless of the operator, the accumulator holds the result. Otherwise the list has at least one element. In that case another predicate, op_val_args/4, delivers the result of the respective operation (Acc1) that is then recursively passed as an accumulator to exprseq_op_val_/4 alongside with the tail of the list (Es):
exprseq_op_val_([],_Op,V,V).
exprseq_op_val_([E1|Es],Op,V,Acc0) :-
expr_val(E1,V1),
op_val_args(Op,Acc1,Acc0,V1),
exprseq_op_val_(Es,Op,V,Acc1).
At last you have to define op_val_args/4, that is again pretty straightforward:
op_val_args(+,V,V1,V2) :-
V is V1+V2.
op_val_args(-,V,V1,V2) :-
V is V1-V2.
op_val_args(*,V,V1,V2) :-
V is V1*V2.
Now let's see how this works. First your example query:
?- expr_val([*,1,[^,2,2],[*,2,[+,[sin,0],5]]],V).
V = 40.0 ? ;
no
The simplest expression according to your specification is a number:
?- expr_val(-3.14,V).
V = -3.14 ? ;
no
The empty list is not an expression:
?- expr_val([],V).
no
The operators +, - and * need at least 2 arguments:
?- expr_val([-],V).
no
?- expr_val([+,1],V).
no
?- expr_val([*,1,2],V).
V = 2 ? ;
no
?- expr_val([-,1,2,3],V).
V = -4 ? ;
no
The power function has exactly two arguments:
?- expr_val([^,1,2,3],V).
no
?- expr_val([^,2,3],V).
V = 8 ? ;
no
?- expr_val([^,2],V).
no
?- expr_val([^],V).
no
And so on...

Prolog, check divisibility in Peano arithmetic

I need to check if first given term (for example s(s(nul)) (or 2)) is dividable by the second term, (for example s(nul) (or 1)).
What I want to do is multiply given term by two and then check if that term is smaller or equal to the other term (if it is equal - problem is solved).
So far I got this:
checkingIfDividable(X,X).
checkingIfDividable(X,Y) :-
X > Y,
multiplication(X,Y).
/* multiplication by two should occur here.
I can't figure it out. This solution does not work!*/
multiplication(Y):-
YY is Y * 2,
checkingIfDividable(X,YY).
I can't seem to figure out how to multiply a term by 2. Any ideas?
If a = n*b, n > 0, it is also a = n*b = (1+m)*b = b + m*b, m >= 0.
So if a is dividable by b, and a = b+x, then x is also dividable by b.
In Peano encoding, n = 1+m is written n = s(m).
Take it from here.

This is about relations on sets

Definition : A relation on set S and T is any subset of the Cartesian product S x T.
Example:
The "larger than" relation for real numbers is the set:
L = {(x, y) | x, y E R, x > y}
Here the part I don't understand it says :
"Here S and T both equal R".
What does it mean?
The elements of set S is equal R and also the elements of set T is eqaul to R.
so S and T is also equal?
The elements of set S is equal R and also the elements of set T is eqaul to R. so S and T is also equal?
Exactly. As both x and y are real numbers, they are taken from the very same set, therefore they are sharing the same domain.

Categorise List in Prolog

Alright so I am coding a parser for arithmetic equations. I get the input in a list, e.g. "10+20" = [49,48,43,50,48] and then I convert all the digits to there corresponding numbers e.g. [49,48,43,50,48] = [1,0,43,2,0] and from there I want to put integers > 10 back together.
Converting from ascii -> digits I use a maplist and number_codes to convert.
One approach I had was to just traverse the list and if it's 0-9 store it in a variable and then check the next number, 0-9 append it to the other variable and so on until I hit an operator. I can't seem to simply append digits as it were. Here's my current code.
expression(L) :-
maplist(chars, L, Ls).
chars(C, N) :-
(
C >= "0", "9" >= C -> number_codes(N, [C]);
N is C
).
Not sure if there's a simple way to add to my code (as far as I know, maplist only gives back a list of equal length to the list passed in but I could be mistaken).
Any help is appreciated :)
Yes, maplist only 'gives back' a list of equal length. Moreover, maplist applies a predicate only to one element (basically it's context-free). Therefore, it is not possible to do what you want (combine digits between operators to a single number) with maplist and you would have to write the recursion yourself.
However, you can do something way easier than all this converting back and forth:
expression(L, E):-
string_to_atom(L,A),
atom_to_term(A,E,[]).
Which works like this:
2 ?- expression("1+2",E).
E = 1+2.
3 ?- expression("1+2",E), X is E.
E = 1+2, X = 3.
4 ?- expression("1+2",E), X+Y = E.
E = 1+2, X = 1, Y = 2.
5 ?- expression("1+2+3",E), X+Y = E.
E = 1+2+3, X = 1+2, Y = 3.
Naturally, if you want a list with all the numbers involved you will have to do something recursive but this is kinda trivial imho.
If however you still want to do the converting, I suggest checking Definite Clause Grammars; it will simplify the task a lot.
I answered some time ago with an expression parser.
It will show you how to use DCG for practical tasks, and I hope you will appreciate the generality and simplicity of such approach.
Just a library predicate is required from SWI-Prolog, number//1, easily implemented in Sicstus. Let me know if you need more help on that.

Resources