Natural deduction: is this a sound proof? - logic

I have attempted to solve the following but I have no means to check it....or does wolfram do this ? I do not know if my handling of the operators (scope) is occrect...do you know?
for all x: upended A operator (universality)
there exists an x: inverted E operator (existence)
for all x(P(x) -> R(x)), for all x(P(x) v not_Q(x)); there exists an x(Q(x)) hold under partial correctness: there exists an x(R(x))
proof:

The structure of your deduction is reasonable, but there are steps missing to take you from the quantified statements to a particular and then back to quantified.
It is not correct to say that P-->Q is "equivalent" to the first premise: that's misrepresenting a predicate statement as a propositional statements. What you can say is that if the first premise holds true for all x, then it is certainly true for one specific x. So universal instantiation of the first premise can give you P(a)-->R(a). Similarly, since the third premise tells us that there is at least one x such that Q(x), we can say let's call one of those x's "a" and so claim Q(a).
Once you get to the point where you have proved R(a) you can then use existential generalisation to get your final conclusion.

I disagree with #MattClarke in that the structure of your reasoning is reasonable. It does not adhere to the rules of natural deduction. For example, your boxed proof assumes Q and ~Q (I am using ~ for negation) and concludes P. But there is no natural deduction rule that allows you to use more than one assumption inside a box (and even if there was, and such a rule could be justified, then the result of the boxed proof is not just P as you seem to claim, but rather the implication (Q /\ ~Q) --> P, which is trivial, since there is already a natural deduction rule that allows us to deduce anything from a contradiction).
From the OP it is not really clear to me what exactly you want to prove. I am just assuming that from the three premises ALL x. (P(x) --> R(x)), ALL x. (P(x) \/ ~Q(x)), and EX x. Q(x) you want to prove EX x. R(x).
Since the formula you want to prove starts with an existential quantifier it will be obtained by exists-introduction. But first we start with the premises:
1 ALL x. (P(x) --> R(x)) premise
2 ALL x. (P(x) \/ ~Q(x)) premise
3 EX x. Q(x) premise
The rule for exists-elimination opens a box (boxes will be indicated by braces { and }) and allows us to conclude a formula that is provable under the assumption that there is a witness for the existential formula to which the rule is applied, i.e.,
4 { for an arbitrary but fixed y that is not used outside this box
5 Q(y) assumption
6 P(y) \/ ~Q(y) ALL-e 2
at this point we apply a disjunction-elimination which amounts to the case analysis whether P(y) holds or ~Q(y) holds (at least one of which has to be true since we have P(y) \/ ~Q(y)). Each case gets its own box
7 {
8 P(y) assumption
9 P(y) --> R(y) ALL-e 1
10 R(y) -->-e 9, 8
11 }
12 {
13 ~Q(y) assumption
14 bottom bottom-i 5, 14
15 R(y) bottom-e 15
16 }
17 R(y) \/-e 6, 7-11, 12-16
18 EX x. R(x) EX-i 17
19 }
20 EX x. R(x) EX-e 3, 4-19

Related

Prolog, Dynamic Programming, Fibonacci series

I should preface this by saying this is a homework problem that I am having issues with, and Im not sure if that sort of thing is allowed around here, but I dont know where else to turn to. This is the question I've been asked:
In the sample code for this question, you can see a Fibonacci predicate fibSimple/2 which calculates the Fibonacci of X, a natural number. The problem with the naive recursive solution, is that you end up recalculating the same recursive case several times. See here for an explanation.
For example, working out the fib(5) involves working out the solution for fib(2) three separate times. A Dynamic Programming approach can solve this problem. Essentially, it boils down to starting with fib(2), then calculating fib(3), then fib(4) etc.... until you reach fib(X). You can store these answers in a list, with fib(X) ending up as the first item in the list.
Your base cases would look like the following:
fib(0,[0]).
fib(1,[1,0]).
Note the way that fib(1) is defined as [1,0]. fib(1) is really 1 but we are keeping a list of previous answers.
Why do we do this? Because to calculate fib(X), we just have to calculate fib(X-1) and add the first two elements together and insert them at the front of the list. For example, from the above, it is easy to calculate fib(2,Ans). fib(2) in this case would be [1,1,0]. Then fib(3) would be [2,1,1,0], fib(4) would be [3,2,1,1,0] etc....
Complete the fib/2 predicate as outlined above - the base cases are shown above. You need to figure out the one line that goes after the base cases to handle the recursion.
This is the sample code they provided
fibSimple(0,0). % fib of 0 is 0
fibSimple(1,1). % fib of 1 is 1
fibSimple(N,X) :- N>1,fibSimple(N-1,A), fibSimple(N-2,B), X is A+B.
fib(0,[0]).
fib(1,[1,0]).
I've had a few attempts at this, and while I'm fairly certain my attempt will end up being hopelessly wrong, this is what I have most recently tried
fib(X,[fib(X-2)+fib(X-1) | _]).
My reasoning to this is that if you can get the answer to the last 2, and add them together making them the first or "head" of the list, and then the underscore representing the rest.
My 2 issues are:
1) I don't know/think this underscore will do what I want it to do, and am lost in where to go from here
and
2) I don't know how to even run this program as the fib\2 predicate requires 2 parameters. And lets say for example I wanted to run fib\2 to find the fibonacci of 5, I would not know what to put as the 2nd parameter.
Because this is homework I will only sketch the solution - but it should answer the questions you asked.
A predicate differs from a function in that it has no return value. Prolog just tells you if it can derive it (*). So if you just ask if fib(5) is true the best you can get is "yes". But what are the Fibonacci numbers from 1 to 5 then? That's where the second argument comes in. Either you already know and check:
?- fib(5, [5, 3, 2, 1, 1, 0]).
true ; <--- Prolog can derive this fact. With ; I see more solutions.
false <--- no, there are no other solutions
Or you leave the second argument as a variable and Prolog will tell you what values that variable must have such that it can derive your query:
?- fib(5, X).
X = [5, 3, 2, 1, 1, 0] ;
false.
So the second argument contains the result you are looking for.
You can also ask the other queries like fib(X,Y) "which numbers and their fibonacci hostories can we derive?" or fib(X, [3 | _]) "which number computes the the fibonacci number 3?". In the second case, we used the underscore to say that the rest of the list does not matter. (2)
So what do we do with fib(X,[fib(X-2)+fib(X-1) | _]).? If we add it to the clauses for 0 and 1 you were given we can just query all results:
?- fib(X,Y).
X = 0,
Y = [1] ; <-- first solution X = 0, Y = [1]
X = 1,
Y = [1, 0] ; <-- second solution X = 1, Y = [1, 0]
Y = [fib(X-2)+fib(X-1)|_2088]. <-- third solution
The third solution just says: a list that begins with the term fib(X-2)+fib(X-1) is a valid solution (the _2088 as just a variable that was not named by you). But as mentioned in the beginning, this term is not evaluated. You would get similar results by defining fib(X, [quetzovercaotl(X-1) | _]).
So similar to fibSimple you need a rule that tells Prolog how to derive new facts from facts it already knows. I have reformatted fibSimple for you:
fibSimple(N,X) :-
N>1,
fibSimple(N-1,A),
fibSimple(N-2,B),
X is A+B.
This says if N > 1 and we can derive fibSimple(N-1,A) and we can derive fibSimple(N-2,B) and we can set X to the result of A + B, then we derive fibSimple(N, X). The difference to what you wrote is that fibSimple(N-1,A) occurs in the body of the rule. Again the argument N-1 does not get evaluated. What actually happens is that the recursion constructs the terms 3-1 and (3-1)-1) when called with the query fib(3,X). The actual evaluation happens in the arithmetic predicates is and <. For example, the recursive predicate stops when it tries to evaluate (3-1)-1 > 1 because 1>1 is not true. But we also do not hit the base case fibSimple(1, 1) because the term (3-1)-1 is not the same as 1 even though they evaluate to the same number.
This is the reason why Prolog does not find the Fibonacci number of 3 in the simple implementation:
?- fibSimple(3, X).
false.
The arithmetic evaluation is done by the is predicate: the query X is (3-1) -1 has exactly the solution X = 1. (3)
So fibSimple must actually look like this: (4)
fibSimple(0,1).
fibSimple(1,1).
fibSimple(N,X) :-
N>1,
M1 is N -1, % evaluate N - 1
M2 is N -2, % evaluate N - 2
fibSimple(M1,A),
fibSimple(M2,B),
X is A+B.
For fib you can use this as a template where you only need one recursive call because both A and B are in the history list. Be careful with the head of your clause: if X is the new value it can not also be the new history list. For example, the head could have the form fib(N, [X | Oldhistory]).
Good luck with the homework!
(1) This is a little simplified - Prolog will usually give you an answer substitution that tells you what values the variables in your query have. There are also some limited ways to deal with non-derivability but you don't need that here.
(2) If you use the arithmetic predicates is and > these two queries will not work with the straightforward implementation. The more declarative way of dealing with this is arithmetic constraints.
(3) For this evaluation to work, the right hand side of is may not contain variables. This is where you would need the arithmetic constraints from (2).
(4) Alternatively, the base cases could evaluate the arithmetic terms that were passed down:
fibSimple(X, 0) :-
0 is X.
fibSimple(X, 1) :-
1 is X.
fibSimple(N,X) :-
N>1,
fibSimple(N-1,A),
fibSimple(N-2,B),
X is A+B.
But this is less efficient because a single number takes much less space than the term 100000 - 1 - 1 -1 .... -1.

Number of legs and heads from Horse and Men in Prolog - RIDDLE

I am currently trying to solve a riddle:
"How many men and horses have 8 heads and 20 feet?"
As I am trying to solve this question with Prolog, my attempt was:
puzzle(M,H,M+H,M*2 + H*4).
And then running:
puzzle(M, H,8,20).
Unfortunately, swipl just returns false.
Can anybody say, why prolog is not working as I was expecting?
To anyone that is interested in a working solution:
horsemen(Man, Horse, Heads, Legs) :-
between(0, Legs, Man),
between(0, Legs, Horse),
Legs is 2*Man + 4*Horse, Heads is Man + Horse.
Anyway, I can't really understand, why the easier solution is not working.
If you write your expression like this:
puzzleSimple(M,M+2).
Prolog will return true for a statement like this :
puzzleSimple(3,3+2). or puzzleSimple(M,M+2).
But it will return false for puzzleSimple(3,5). What you see here is that, prolog will not execute the M+2as an arithmetic operation but rather use it in pattern matching. For arithmetic operations, you need to use the is keyword. For example:
puzzleSimple(M,V):-
V is M + 2.
This code will return true for puzzleSimple(3,5). So, when you try to directly use
puzzle(M,H,M+H,M*2 + H*4). and call puzzle(M, H,8,20).
It returns false, because the pattern is not matching.
You can also modify the code to this:
puzzle(M,H,X,Y):-
X is M+H,
Y is M*2 + H*4.
Now it will be correct in the sense of pattern matching and arithmetic operations. However, when you again call puzzle(M, H,8,20). You will see an Arguments are not sufficiently instantiated error. Why? Because you tried to do an arithmetic operation with a variable which is not instantiated. That is why the working solution uses the predicate between/3. Between assigns a value to a variable and enables the use of backtracking for finding multiple solutions.
Note : Using the gtrace command in swipl can help you in debugging your code!
You can solve it using the library "CLP(FD) Constraint Logic Programming over Finite Domains".
:-use_module(library(clpfd)).
%% "How many men and horses have 8 heads and 20 feet?"
men_and_horses(Men, Horses):-
Men in 0..10,
Horses in 0..10,
Men + Horses #= 8, %% heads must be 8
Men * 2 + Horses * 4 #= 20. %% feet mus be 20
The solution is
?- men_and_horses(X,Y).
X = 6,
Y = 2.

Prolog Loops until True

I'm pretty new to Prolog but I'm trying to get this program to give me the first set of twin primes that appears either at or above N.
twins(M) :-
M2 is M + 2,
twin_prime(M, M2),
write(M),
write(' '),
write(M2).
M3 is M + 1,
twins(M3).
However, I'm not completely sure how to go about getting it to loop and repeat until it's true. I've tried using the repeat/0 predicate but I just get stuck in an infinite loop. Does anyone have any tips I could try? I'm pretty new to Prolog.
You're on the right track using tail recursion and #Jake Mitchell's solution works swell. But here are some tips that might help clarify a few basic concepts in Prolog:
First, it seems like your predicate twins/1 is actually defining a relationship between 2 numbers, namely, the two twin primes. Since Prolog is great for writing very clear, declarative, relational programs, you might make the predicate more precise and explicit by making it twin_primes/2. (That this should be a binary predicate is also pretty clear from your name for the predicate, since one thing cannot be twins...)
One nice bonus of explicitly working with a binary predicate when describing binary relations is that we no longer have to fuss with IO operations to display our results. We'll simply be able to query twin_primes(X,Y) and have the results returned as Prolog reports back on viable values of X and Y.
Second, and more importantly, your current definition of twins/1 wants to describe a disjunction: "twins(M) is true if M and M + 2 are both prime or if M3 is M + 3 and twins(M3) is true". The basic way of expressing disjunctions like this is by writing multiple clauses. A single clause of the form <Head> :- <Body> declares that the Head is true if all the statements composing the Body are true. Several clauses with the same head, like <Head> :- <Body1>. <Head> :- <Body2>. ..., declare that Head is true if Body1 is true or if Body2 is true. (Note that a series of clauses defining rules for a predicate are evaluated sequentially, from top to bottom. This is pretty important, since it introduces non-declarative elements into the foundations of our programs, and it can be exploited to achieve certain results.)
In fact, you are only a small step from declaring a second rule for twins/1. You just tried putting both clause-bodies under the same head instance. Prolog requires the redundant measure of declaring two different rules in cases like this. Your code should be fine (assuming your definition of twin_prime/2 works), if you just change it like so:
twins(M) :-
M2 is M + 2,
twin_prime(M, M2),
write(M),
write(' '),
write(M2).
twins(M) :-
\+twin_prime(M, M2), %% `\+` means "not"
M3 is M + 1,
twins(M3).
Note that if you take advantage of Prolog's back-tracking, you often don't actually need to effect loops through tail recursion. For example, here's an alternative approach, taking into account some of what I advised previously and using a quick (but not as in "efficient" or "fast") and dirty predicate for generating primes:
prime(2).
prime(P) :-
between(2,inf,P),
N is (P // 2 + 1),
forall(between(2,N,Divisor), \+(0 is P mod Divisor)).
twin_primes(P1, P2) :-
prime(P1),
P2 is P1 + 2,
prime(P2).
twin_primes/2 gets a prime number from prime/1, then calculates P2 and checks if it is prime. Since prime/1 will generate an infinite number of primes on backtracking, twin_primes/2 will just keep asking it for numbers until it finds a satisfactory solution. Note that, if called with two free variables, this twin_primes/2 will generate twin primes:
?- twin_primes(P1, P2).
P1 = 3,
P2 = 5 ;
P1 = 5,
P2 = 7 ;
P1 = 11,
P2 = 13 ;
P1 = 17,
P2 = 19 ;
P1 = 29,
P2 = 31 ;
But it will also verify if two numbers are twin primes if queried with specific values, or give you the twin of a prime, if it exists, if you give a value for P1 but leave P2 free:
?- twin_primes(3,Y). Y = 5.
There's a handy if-then-else operator that works well for this.
twin_prime(3,5).
twin_prime(5,7).
twin_prime(11,13).
next_twin(N) :-
A is N+1,
B is N+2,
(twin_prime(N,B) ->
write(N),
write(' '),
write(B)
;
next_twin(A)).
And a quick test:
?- next_twin(5).
5 7
true.
?- next_twin(6).
11 13
true.

How does a Resolution algorithm work for propositional logic?

I haven't been able to understand what the resolution rule is in propositional logic. Does resolution simply state some rules by which a sentence can be expanded and written in another form?
Following is a simple resolution algorithm for propositional logic. The function returns the set of all possible clauses obtained by resolving it's 2 input. I can't understand the working of the algorithm, could someone explain it to me?
function PL-RESOLUTION(KB,α) returns true or false
inputs: KB, the knowledge base, a sentence α in propositional logic, the query, a
sentence in propositional logic
clauses <--- the set of clauses in the CNF representation of KB ∧ ¬α
new <--- {}
loop do
for each Ci, Cj in clauses do
resolvents <----- PL-RESOLVE(Ci, Cj)
if resolvents contains the empty clause then return true
new <--- new ∪ resolvents
if new ⊆ clauses then return false
clauses <---- clauses ∪ new
It's a whole topic of discussion but I'll try to explain you one simple example.
Input of your algorithm is KB - set of rules to perform resolution. It easy to understand that as set of facts like:
Apple is red
If smth is red Then this smth is sweet
We introduce two predicates R(x) - (x is red) and S(x) - (x is sweet). Than we can written our facts in formal language:
R('apple')
R(X) -> S(X)
We can substitute 2nd fact as ¬R v S to be eligible for resolution rule.
Caluclating resolvents step in your programs delete two opposite facts:
Examples: 1) a & ¬a -> empty. 2) a('b') & ¬a(x) v s(x) -> S('b')
Note that in second example variable x substituted with actual value 'b'.
The goal of our program to determine if sentence apple is sweet is true. We write this sentence also in formal language as S('apple') and ask it in inverted state. Then formal definition of problem is:
CLAUSE1 = R('apple')
CLAUSE2 = ¬R(X) v S(X)
Goal? = ¬S('apple')
Algorithm works as follows:
Take clause c1 and c2
calculate resolvents for c1 and c2 gives new clause c3 = S('apple')
calculate resolvents for c3 and goal gives us empty set.
That means our sentence is true. If you can't get empty set with such resolutions that means sentence is false (but for most cases in practical applications it's a lack of KB facts).
Consider clauses X and Y, with X = {a, x1, x2, ..., xm} and Y = {~a, y1, y2, ..., yn}, where a is a variable, ~a is its negation, and the xi and yi are literals (i.e., possibly-negated variables).
The interpretation of X is the proposition (a \/ x1 \/ x2 \/ ... \/ xm) -- that is, at least one of a or one of the xi must be true, assuming X is true. Likewise for Y.
We assume that X and Y are true.
We also know that (a \/ ~a) is always true, regardless of the value of a.
If ~a is true, then a is false, so ~a /\ X => {x1, x2, ..., xm}.
If a is true, then ~a is false. In this case a /\ Y => {y1, y2, ..., yn}.
We know, therefore, that {x1, x2, ..., xm, y1, y2, ..., yn} must be true, assuming X and Y are true. Observe that the new clause does not refer to variable a.
This kind of deduction is known as resolution.
How does this work in a resolution based theorem prover? Simple: we use proof by contradiction. That is, we start by turning our "facts" into clauses and add the clauses corresponding to the negation of our "goal". Then, if we can eventually resolve to the empty clause, {}, we will have reached a contradiction since the empty clause is equivalent to falsity. Because the facts are given, this means that our negated goal must be wrong, hence the (unnegated) goal must be true.
resolution is a procedure used in proving that argument which are expressible in predicate logic are correct
resolution lead to refute theorem proving technique for sentences in propositional logic.
resolution provides proof by refutation. i.e. to show that it is valid,resolution attempts to show that the negation of the statement produces a contradiction with a known statement
algorithm:
1). convert all the propositions of axioms to clause form
2). negate propositions & convert result to clause form
3)resolve them
4)if the resolvent is the empty clause, then contradiction has been found

Can the negation introduction rule of inference "a, b=>¬a / ¬b" be used instead of the usual "b=>a, b=>¬a / ¬b"?

I find the negation introduction rule which I learned at university a bit confusing to reason out and think that "a, b=>¬a / ¬b" makes more sense as it means that if b implies something which is not true, then b is itself not true. I can't seem to find an example of where the usual rule is more useful than the one I would like to use. Is there a reason why "b=>a, b=>¬a / ¬b" is used as a rule?
OK, I think I have a pretty rigorous argument which validates said replacement.
Let's say that we need to introduce a negation on P. So using the usual inference rule, we prove
P => Q
P => ¬Q
and thereby prove ¬P.
Let's say that there is no way to derive both Q and ¬Q if P is not assumed. But then from P we can derive Q /\ ¬Q which will allow us to derive anything, including the negation of a tautology.
So we can prove ¬P using the proposed rule by doing something like this:
1. |P Assumed
... |...
10. |Q
... |...
20. |¬Q
21. |Q /\ ¬Q /\ introduction on line 10 and 20
22. |¬(A => A) Derived from line 21 using contradiction lemma
23. P => ¬(A => A) => introduction on lines 1-22
24. A => A Anything implies itself (a tautology)
25. ¬P ¬ introduction on line 23 and 24
So using tautologies we can always use the proposed rule of inference.
In other words, if you can use the usual rule of inference to introduce a negation, you can use the proposed rule of inference too.

Resources