I am trying a theorem proving program. But Rule 4 seems to be badly implemented.
% delete
del(X, [X | Tail], Tail).
del(X, [Y | Tail], [Y | Tail1]) :-
del(X, Tail, Tail1).
% remove
remove(X, Y, L1, L2) :-
del(X, L1, L3),
del(Y, L3, L2).
% prove
prove(true).
prove([L1 seq L2]) :-
seq(L1, L2),
!.
% Rule 1
seq(L1, L2) :-
member(X, L1),
member(X, L2),
!.
% Rule 4
seq(L1, L2) :-
Z = or(X, Y),
del(Z, L2, L4),
remove(X, Y, L3, L4),
seq(L1, L3).
prove([[p] seq [q]]). -- Generates false, which is correct.
prove([[p] seq [q, r]]). -- Generates false, correct.
But prove([[p] seq [q or r]]). -- Out of global stack. Then I think there is something wrong with Rule 4.
Any idea how to fix this problem? Thanks a lot.
In Rule 4, as best I can tell, you
Set Z to be a template for an or
Try to remove that template from L2, so that L4 is what gets left behind, and the components of that template (X and Y) get filled in,
Find an L3 from which the components of the or can be removed to also give L4,
And then you try to solve the problem with L3 instead of L2
But this means that L3 isn't necessarily making any progress toward termination.
Related
I have to implement a function that takes two lists of tuples let foo l1 l2 and has to append them and apply a recursive function let rec bar x l to one element of each tuple in the list.
The number of recursive calls depends on l, so I'd like to use the intermediate results of the pipe as l in order to reduce the calls instead of saving the initial list and pass that one.
My current solution is as follows and I'd like to optimise it with some sort of dynamic programming solution
let foo l1 l2 =
l = l1 # l2
l |> List.map (fun (x, y) -> x, bar y l)
what's the difference between
L1 = {m ∈ (a + b)*} L1 = {m ∈ (a , b)*}
i feel like there is no difference but i cant really understand the difference between this + and the plus in this expression for example (a,b)+
You are correct, there is no difference. a+b translates to a union b and (a , b) is another (albeit much less common) way that some researchers refer to a union b. If you so choose to continue your study of automata you will find that there is an incredible variety of ways that different researchers refer to the same concepts. In this instance alone, off the top of my head I know this can be written as:
L1 = {m ∈ (a + b)*}
L1 = {m ∈ (a , b)*}
L1 = {m ∈ (a | b)*}
L1 = {m ∈ (a U b)*}
I'm looking for a tool for determining whether a given set of linear equations/inequalities (A) entails another given set of linear equations/inequalities (B). The return value should be either 'true' or 'false'.
To illustrate, let's look at possible instances of A and B and the expected return value of the algorithm:
A: {Z=3,Y=Z+2, X < Y} ;
B: {X<5} ;
Expected result: true
A: {Z=3,Y=Z+2, X < Y} ;
B: {X<10} ;
Expected result: true
A: {Z=3,Y=Z+2, X < Y} ;
B: {X=3} ;
Expected result: false
A: {X<=Y,X>=Y} ;
B: {X=Y} ;
Expected result: true
A: {X<=Y,X>=Y} ;
B: {X=Y, X>Z+2} ;
Expected result: false
Typically A contains up to 10 equations/inequalities, and B contains 1 or 2. All of them are linear and relatively simple. We may even assume that all variables are integers.
This task - of determining whether A entails B - is part of a bigger system and therefore I'm looking for tools/source code/packages that already implemented something like that and I can use.
Things I started to look at:
Theorem provers with algebra - Otter, EQP and Z3 (Vampire is currently unavailable for download).
Coq formal proof management system.
Linear Programming.
However, my experience with these tools is very limited and so far I didn't find a promising direction. Any guidelines and ideas from people more experienced than me will be highly appreciated.
Thank you for your time!
I think I found a working solution. The problem can be rephrased as an assignment problem and then it can be solved by theorem provers such as Z3 and with some work probably also by linear programming solvers.
To illustrate, let's look at the first example I gave above:
A: {Z=3, Y=Z+2, X<Y} ;
B: {X<5} ;
Determining whether A entails B is equivalent to determining whether it is impossible that A is true while B is false. This is a simple simple logical equivalence. In our case, it means that rather than checking whether the condition in B follows from the ones in A, we can check whether there is no assignment of X, Y and Z that satisfies the conditions in A and not in B.
Now, when phrased as an assignment problem, a theorem prover such as Z3 can be called for the task. The following code checks if the conditions in A are satisfiable while the one in B is not:
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (= z 3))
(assert (= y (+ z 2)))
(assert (< x y))
(assert (not (< x 5)))
(check-sat)
(get-model)
(exit)
Z3 reports that there is no model that satisfies these conditions, thus it is not possible that B doesn't follow from A, and therefore we can conclude that B follows from A.
For the code below, I am unable to comprehend how the bindings (x, y, z) occur. Please check out the code, I'll explain my problem in greater detail below:
(define (w x)
(lambda (y z)
(begin
(set! x (+ (* y x) z)) x)))
(define f1 (w 3))
(f1 4 2)
(f1 2 1)
The output is 14, 29. These are values for x.
This means initially, x=3, y=4, z=2. In the 2nd call, i.e. (f1 2 1), x=14, y=2,z=1.
My doubts:
How does the binding occur at first, why is x=3, y=4, and z=2? If it has got to do with lambda expression in the function, please elaborate on how it works..I have a feeling this is where my understanding breaks down..
Next, why is the initial answer of x=14 retained in the second call, i.e. (f1 2 1)?
Thank you for looking into this :)
When w is run, it creates a closure out of the inner lambda. Because x came from outside of that inner lambda, x is stored inside that closure (in this case, f1).
So, f1 has a variable inside that represents x, and it starts out as 3. When you run f1, it evaluates the math and then sets its own x to be 14.
The moral is, a lambda is more than just code; it's code combined with the variables it closes over, such as this x.
I have the following problem:
Languages L1 = {a^n * b^n : n>=0} and L2 = {b^n * a^n : n>=0} are
context free languages so they are closed under the L1L2 so L={a^n *
b^2n A^n : n>=0} must be context free too because it is generated by a
closure property.
I have to prove if this is true or not.
So I checked the L language and I don’t think that it is context free then I also saw that L2 is just L1 reversed.
Do I have to check if L1, L2 are deterministic?
L1={anbn : n>=0} and L2={bnan : n>=0} are both
context free.
Since context-free languages are closed under concatenation, L3=L1L2 is also context-free.
However, L3 is not the same language as L4={anb2nan : n >= 0}.
The string abbbaa is in L3, but not L4.
So is L4 context-free? If so, it must obey the pumping lemma for context-free languages.
Let p be the pumping length of L4. Choose s = apb2pap.
Then s is in L4, and |s| > p. Therefore, if L4 is context-free, we can write s
as uvxyz, with |vxy| <= p, |vy| >= 1, and uvnxynz is in L4 for
any n >= 0.
Observe the following properties of any nonempty string in L4: The count of a's equals the count of b's. There is exactly one occurrence of the substring 'ab', and exactly one
occurrence of the substring 'ba'. The length of the initial string of a's equals the length of the final string of a's.
We can use these observations to constrain the possible choices of v and y in our pumping argument for L4. Neither v nor y can contain the substring 'ab', because then, as v and y are pumped an arbitrary number of times, the output string would contain multiple occurrences of 'ab', and therefore cannot be an element of L4. The same argument applies to the substring 'ba'.
So v must be either empty, all a's, or all b's. The same applies to y.
Furthermore, if v is all a's, then y must consist of the same number of b's; otherwise, the pumped string would contain unequal numbers of a's and b's since v and y are pumped by
the same n. Likewise, if v is all b's, then y must be the same number of a's.
But if v is all a's, and y is all b's, the final string of a's is unaffected by pumping v and y, therefore the leading string of a's will no longer match the trailing string of a's.
Similarly, if v is all b's and y is all a's, the leading and trailing strings of a's will again have different lengths as v and y are pumped.
v and y cannot both be empty, since that would violate the condition |vy| >= 1 for
the CFL pumping lemma. But since we have established that |v| = |y|, it follows
that neither v nor y can be empty.
But if v cannot be empty, cannot be all a's, cannot be all b's, and cannot contain
the substrings 'ab' or 'ba', then there is no possible choice of uvxyz for which
the pumped version of s is still in L4. Therefore L4 is not context-free.
I'm not sure that it is -- note that in each of the defintions of L1 and L2, n is scoped within that definition, i.e. they are two different variables. When you combine them you should rename one, and get instead:
L = {a^n * b^n b^m * a^m : n,m>=0}
This is a very different language from your L, but it is obviously a context free one.