How to parse? top down parsing not possible? - parsing

We have to parse this two words:
"abccdef"
"cabddc"
but with:
S->aBC
B->b|dc
C->aD
D-ac
?? How is it possible to parse this words with that? Is that a misstake in the task?

As posted in my comment above, if in doubt, code it.
Of course, you can see that the characters e and f are not part of the parser rules and as such, it is kind of obvious.
Unless, of course, I misunderstood your D production rule. This is one reason, why you should always explain a bit more about your problem. The D-ac might be a local convention for something, the majority of people here cannot interpret. I considered it a typo, meaning the same as D->ac.
Here is how it looks in Common Lisp:
(defun parser (s &optional (n (length s)) (i 0) (state :s))
(when i
(if (= i n)
i
(let ((c (char s i)))
(ecase state
(:s
(when (char-equal c #\a)
(parser s n (parser s n (+ i 1) :b) :c)))
(:b
(when (and (or (char-equal c #\b) (char-equal c #\d))
(< (+ i 1) n)
(char-equal (char s (+ i 1)) #\c))
(+ i 2)))
(:c
(when (char-equal c #\a)
(parser s n (+ i 1) :d)))
(:d
(when (and (char-equal c #\a)
(< (+ i 1) n)
(char-equal (char s (+ i 1)) #\c))
(+ i 2))))))))
I use the symbols :s, :b, :c and :d as state information (which production rule is the current state of the program).
Translated to pleb, which might be a language you have seen before, it looks like this (I only had pleb 3.9 and so there is no switch case syntax in that language, since someone added it later in version 3.10. My version also has no enum built into the language, so I just misused a class for that.):
class State:
S = 1
B = 2
C = 3
D = 4
def parser(s,i=0,state=State.S):
n=len(s)
if i == n:
return i
else:
c = s[i]
if state == State.S:
if c == 'a':
return parser(s,
parser(s,i+1,State.B),
State.C)
elif state == State.B:
if (c == 'b' or c == 'd') and (i+1)<n and s[i+1]== 'c':
return i+2
elif state == State.C:
if c == 'a':
return parser(s,i+1,State.D)
elif state == State.D:
if c == 'a' and (i+1)<n and s[i+1] == 'c':
return i+2
else:
raise ValueError("Unknown parser state!")
Running either of the above, with your given strings, they return NIL or nothing, respectively and if you run it with an input, which conforms to the grammar, e.g. "abcaac" or "adcaac", you get the length of the input as return value.

Related

how do I compare 3 numbers in sml?

I am trying to come up with an function that takes 3 numbers as input and returns the largest number among them. My code is as following:
fun max3(a,b,c)=
if a >= b andalso a >= c then a
else if b >= a andalso b >= c then b
else if c >= a andalso c >= b then c;
However, I get the following errors:
Error: syntax error: inserting LET
Error: syntax error: replacing SEMICOLON with EQUALOP
Error: syntax error found at EOF
Did I do something wrong?
Every time you have an if, you need a then and an else. You can see how this becomes a problem by changing how you indent things.
fun max3(a,b,c)=
if a >= b andalso a >= c
then a
else if b >= a andalso b >= c
then b
else if c >= a andalso c >= b
then c
(* notice how there is no else here? *)
;
However, you can simplify the logic a lot:
fun max3(a,b,c)=
if a >= b andalso a >= c then
(* a is the largest of a, b and c *)
a
else
(* a is not the largest, so either b or c is the largest *)
if b >= c then
(* b is the largest of the two *)
b
else
(* c is the largest of the two *)
c
I would reduce this problem to an already solved one:
fun max3 (a, b, c) = max2 (a, max2 (b, c))
where
fun max2 (a, b) = if a > b then a else b
or simply
val max2 = Int.max

Z3Python: ForAll causes my code hangup, or returns Unsat, why?

I am still struggling with the problem of findiong a value so that a * b == b with all value of b. The expected result is a == 1. I have two solutions below.
(A) I implemented this with ForAll quantifier in below code (correct me if there is a solution without using any quantifier). The idea is to prove f and g are equivalent.
from z3 import *
a, b, a1, tmp1 = BitVecs('a b a1 tmp1', 32)
f = True
f = And(f, tmp1 == b)
f = And(f, a1 == a * tmp1)
g= True
g = And(g, a1 == b)
s = Solver()
s.add(ForAll([b, tmp1, a1], f == g))
if s.check() == sat:
print 'a =', s.model()[a]
else:
print 'Unsat'
However, this simple code runs forever without giving back result. I think that is because of the ForAll. Any idea on how to fix the problem?
(B) I tried again with another version. This time I dont prove two formulas to be equivalent, but put them all into one formula f. Logically, I think this is true, but please correct me if I am wrong here:
from z3 import *
a, b, a1, tmp = BitVecs('a b a1 tmp', 32)
f = True
f = And(f, tmp == b)
f = And(f, a1 == a * tmp)
f = And(f, a1 == b)
s = Solver()
s.add(ForAll([b, a1], f))
if s.check() == sat:
print 'a =', s.model()[a]
else:
print 'Unsat'
This time the code does not hang, but immediately returns 'Unsat'. Any idea on how to fix this?
Thanks a lot.
The direct formulation of your problem provides the answer you were expecting: http://rise4fun.com/Z3Py/N07sW
The versions you propose use auxiliary variables, a1, tmp, tmp1 and you
use universal quantification over these variables. This does not correspond
to the formula you intended.

why this code returns Unsat?

Given c == a + 4 and t == c + b, if b == -4, then t == a. I am trying to do the opposite, meaning given the above 2 equations and t == a, I try to find value of b.
This is pretty similar to the related question, but this time I only switch a and b, and I am really confused that the code returns different result.
Following the code posted at above link, I have below code (similar, only a and b swiched):
#!/usr/bin/python
from z3 import *
a, b, c, t = BitVecs('a b c t', 32)
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
s = Solver()
s.add(ForAll([t, a, c], Implies(t == a, g)))
if s.check() == sat:
print s.model()[b]
else:
print 'Unsat'
However, on Ubuntu, running the above code returns unexpected result Unsat, but not value -4 (or 0xfffffffc)
Any idea why this is wrong?
Thanks so much.
Z3 is actually returning unknown. The method check returns: sat, unsat or unknown.
Here is a custom tactic that shows that the formula is indeed unsat.
#!/usr/bin/python
from z3 import *
a, b, c, t = BitVecs('a b c t', 32)
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
s = Goal()
s.add(ForAll([t, a, c], Implies(t == a, g)))
T = Then("simplify", "der", "distribute-forall")
# print the simplified formula. Note that it is unsat
print T(s)
# Create a solver using the tactic above and qe
s = Then("simplify", "der", "distribute-forall", "qe", "smt").solver()
s.add(ForAll([t, a, c], Implies(t == a, g)))
print s.check()
Update
The formula is of the form
forall t, a, c: t == a ==> c == (a + 4) and t == (c + b).
This formula is logically equivalent to:
forall a, c: c == (a + 4) and a == (c + b).
which is logically equivalent to
(forall a, c: c == (a + 4)) and (forall a, c: a == (c + b)).
Both subformulas are logically equivalent to false.
This is why the formula is unsatisfiable.
The comment you wrote suggests that you believe you created the slightly different formula
forall t, a, c: t == a ==> c == (a + 4) ==> t == (c + b).
This formula is sat. To create this formula we have to replace
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
with
g = Implies(c == (a + 4), t == (c + b))
The updated example is available here.

Print first N prime numbers in Common Lisp

I am making a Common Lisp function to print the first N prime numbers. So far I've managed to write this code:
;globals
(setf isprime 1) ;if 1 then its a prime, 0 if not.
(setf from 1) ;start from 1
(setf count 0) ;should act as counter to check if we have already
; N primes printed
;function so far.
(defun prime-numbers (to)
(if (> count to) nil(progn
(is-prime from from)
(if (= isprime 1) (print from)(setf count (+ count 1)))
(setf isprime 1)
(setf from (+ from 1))
(prime-numbers to)))
(if (>= count to)(setf count 0) (setf from 1)))
;code to check if a number is prime
(defun is-prime(num val)
(if (< num 3) nil
(progn
(if (= (mod val (- num 1)) 0) (setf isprime 0))
(is-prime (- num 1) val))))
My problem is, it does not print N primes correctly.
If I call >(prime-numbers 10),
results are:
1
2
3
5
7
11
13
17
19
1,
i.e. it printed only 9 primes correctly.
but then if i call >(prime-numbers 2)
the results are: 1
2
3
5
7
1
what am I doing wrong here?? this is my first time to code in LISP.
UPDATE:
(defparameter from 1)
(defparameter count 0)
(defun prime-numbers (to)
(if (> count to)nil
(progn
(when (is-prime from)
(print from)
(setf count (+ count 1)))
(setf from (+ from 1))
(prime-numbers to)))
(when (>= count to)
(setf count 0)
(setf from 1)))
(defun is-prime (n)
(cond ((= 2 n) t)
((= 3 n) t)
((evenp n) nil)
(t
(loop for i from 3 to (isqrt n) by 2
never (zerop (mod n i))))))
works fine. but outputs a NIL at the end.
First, there's no need to use globals here, at all.
Use true/false return values. That would allow your is-prime function to be something like:
(defun is-prime (n)
(cond ((= 2 n) t) ;; Hard-code "2 is a prime"
((= 3 n) t) ;; Hard-code "3 is a prime"
((evenp n) nil) ;; If we're looking at an even now, it's not a prime
(t ;; If it is divisible by an odd number below its square root, it's not prime
(loop for i from 3 to (isqrt n) by 2
never (zerop (mod n i))))))
That way, the function is not relying on any external state and there's nothing that can confuse anything.
Second, the last 1 you see is (probably) the return value from the function.
To check that, try:
(progn (prime-numbers 10) nil)
Third, re-write your prime-numbers function to not use global variables.
Fourth, never create global variables with setf or setq, use either defvar or defparameter. It's also (mostly, but some disagree) good style to use *earmuffs* on your global (really, "special") variables.
To expand on Vatines answer:
A possible rewrite of the prime-numbers function, using the same algoritm but avoiding globals is
(defun prime-numbers (num &optional (from 2))
(cond ((<= num 0) nil)
((is-prime from) (cons from (prime-numbers (1- num) (1+ from))))
(t (prime-numbers num (1+ from)))))
This function also returns the primes instead of printing them.
The problem with this recursive solution is it consumes stack for each prime found/tested. Thus stack space may be exhausted for large values of num.
A non-recursive variant is
(defun prime-numbers (num &optional (start 2))
(loop for n upfrom start
when (is-prime n)
sum 1 into count
and collect n
until (>= count num)))

unsat core function in z3

Suppose I read the SMTLIB formula using the API:
context ctx;
...
expr F = to_expr(ctx, Z3_parse_smtlib2_file(ctx,argv[1],0,0,0,0,0,0));
The expression F is a conjunction of assertions of the form:
(and (< (+ x y) 3)
(> (- x1 x2) 0)
(< (- x1 x2) 4)
(not (= (- x1 x2) 1))
(not (= (- x1 x2) 2))
(not (= (- x1 x2) 3)))
I'd like to extract each individual assertion from this conjunction using the following code fragment from post: How to use z3 split clauses of unsat cores & try to find out unsat core again
F = F.simplify();
for (unsigned i = 0; i < F.num_args(); i++) {
expr Ai = F.arg(i);
// ... Do something with Ai, just printing in this example.
std::cout << Ai << "\n";
}
After utilizing the F.arg(i), the original clause (< (+ x y) 3) has been changed into (not (<= 3 (+ x y))). Here is my
a) question : How can I place the clause (not (<= 3 (+ x y))) to (< (+ x y) 3) ?
b) question : I consider the symbol <= mean to imply in this case, not mean to less than. Am I right?
c) question : Because the clause (not (<= 3 (+ x y))) model is true or false, how can I get arithmetic values such as x = 1, y = -1?
It's very grateful for any suggestion.
Thank you very much.
The expression (< (+ x y) 3) is transformed into (not (<= 3 (+ x y))) when F = F.simplify().
In the code fragment you used, the method simplify() is used to "flat" nested "and"s. That is, a formula (and (and A B) (and C (and D E))) is flattened into (and A B C D E). Then, all conjuncts can be easily traversed using the for-loop. However, the simplify() will also perform other transformations in the input formula. Keep in mind, that all transformation preserve equivalence. That is, the input and output formula are logically equivalent. If the transformations applied by simplify() are not desirable, I suggest you avoid this method. If you still want to traverse nested "and"s, you can use an auxiliary todo vector. Here is an example:
expr_vector todo(c);
todo.push_back(F);
while (!todo.empty()) {
expr current = todo.back();
todo.pop_back();
if (current.decl().decl_kind() == Z3_OP_AND) {
// it is an AND, then put children into the todo list
for (unsigned i = 0; i < current.num_args(); i++) {
todo.push_back(current.arg(i));
}
}
else {
// do something with current
std::cout << current << "\n";
}
}

Resources