Dafny proof by contradiction with quantifiers - proof

I'm trying to write a proof by contradiction in Dafny for the union of transitive relations being also transitive and I'm not quite sure how to form the arguments with dafny syntax. Can I just show one counter example or do I need to write out all possible cases? Secondly, do I need to relax/restate the conclusion to that there exists some unions of transitive relations which are not also transitive?
predicate relationOnASet<T>(R: set<(T,T)>, S: set<T>) {
forall ts :: ts in R ==> ts.0 in S && ts.1 in S
}
predicate transitive<T>(R: set<(T,T)>, S: set<T>)
requires relationOnASet(R, S)
{
forall a,b,c :: a in S && b in S && c in S && (a,b) in R && (b,c) in R ==> (a,c) in R
}
lemma transitiveUnionContra<T>(R_1: set<(T,T)>, S_1: set<T>, R_2: set<(T,T)>, S_2: set<T>)
requires |R_1| > 0
requires |R_2| > 0
requires |S_1| > 0
requires |S_2| > 0
requires relationOnASet(R_1, S_1)
requires relationOnASet(R_2, S_2)
requires transitive(R_1, S_1)
requires transitive(R_2, S_2)
ensures !transitive(R_1+R_2, S_1+S_2)
{
if transitive(R_1 + R_2, S_1+S_2) {
forall a,b,c | a in S_1+S_2 && b in S_1+S_2 && c in S_1+S_2 && (a,b) in R_1+R_2 && (b,c) in R_1+R_2
ensures (a,c) in R_1+R_2
{
if a in S_1 && a !in S_2 && b in S_1 && b in S_2 && c in S_2 && c !in S_1 {
assert (a,c) !in R_1;
assert (a,c) !in R_2;
assert (a,c) !in R_1+R_2;
assert false;
}
}
}
}

Your lemma says that for every transitive relations R_1, R_2 it is not case that R_1 + R_2 is transitive relation. But there do exists such relation R_1 = {(a, b)} and R_2 = {(a, b), (b, c), (a, c)}.
Here is an attempt to express original lemma in dafny.
predicate relationOnASet<T> (R : set<(T,T)>, S : set<T>) {
forall ts :: ts in R ==> ts.0 in S && ts.1 in S
}
predicate transitive<T>(R: set<(T,T)>, S: set<T>)
requires relationOnASet(R, S)
{
forall a, b, c ::
a in S &&
b in S &&
c in S &&
(a, b) in R &&
(b, c) in R ==> (a, c) in R
}
lemma transitiveUnionContra<T>()
returns (
R1: set<(T, T)>, S1: set<T>,
R2: set<(T, T)>, S2: set<T>)
ensures relationOnASet(R1, S1)
ensures relationOnASet(R2, S2)
ensures transitive(R1, S1)
ensures transitive(R2, S2)
ensures ! transitive(R1 + R2, S1 + S2)
{
var a : T :| assume true;
var b : T :| assume a != b;
var c : T :| assume a != c && b != c;
S1 := {a, b};
S2 := {b, c};
R1 := {(a, b)};
R2 := {(b, c)};
}
lemma notTrueAlways<T>()
ensures !
(forall S1 : set<T>, S2 : set<T>, R1 : set<(T,T)>, R2 : set<(T, T)> ::
relationOnASet(R1, S1) &&
relationOnASet(R2, S2) &&
transitive(R1, S1) &&
transitive(R2, S2) ==> transitive(R1 + R2, S1 + S2)
)
{
var a, b, c, d := transitiveUnionContra<T>();
}
Using few assumes to pull three different element out of type out of thin air.

Related

Dafny GCD lemma Proof

I'd like to use dafny to prove the following lemma about GCD: For all k natural numbers, if k|a and k|b, then k|gcd(a,b). I have the following code so far:
// Euclid's algorithm for computing the greatest common divisor
function gcd(a: nat, b: nat): nat
requires a > 0 && b > 0
{
if a == b then a else
if b > a then gcd(a, b - a) else
gcd(a - b, b)
}
predicate divides(a: nat, b:nat)
requires a > 0
{
exists k: nat :: b == k * a
}
lemma dividesLemma(a: nat, b: nat)
//k|a && k|b ==> k|gcd(a,b)
requires a > 0 && b > 0
ensures gcd(a,b) > 0
ensures forall k: nat :: divides(a,k) && divides(b,k) ==> divides(gcd(a,b),k)
{
if(a == b) {
assert a * 1 == gcd(a,b);
assert b * 1 == gcd(a,b);
} else if b > a {
if(divides(a, b)) {
assert divides(a,a);
assert divides(a,b);
assert divides(a, gcd(a,b));
} else {
dividesLemma(a, b - a);
}
} else {
if(divides(b, a)) {
assert divides(b,b);
assert divides(b,a);
assert divides(b, gcd(a,b));
} else {
dividesLemma(a, a - b);
}
}
}
I know how to do the proof for this by hand. I would consider the prime factorization of a and b and say that gcd(a,b) was the combined prime factorization such that we take the minimal number of primes from each prime factorization. For instance if a = 9 and b = 15, the prime factorization of 9 = 3x3 and the prime factorization of 15 = 3x5, so the gcd(9,5) = 3 since that's the minimal combination of their prime factoizations. Using this fact it should be clear that if k|b and k|a, k must contain those minimal primes. How can I express this using dafny? Currently, I'm considering the base case if a=b and if a|b or b|a, but not sure how to incorporate the fact that it's possible for a and b to not share common primes in their prime factorizations.
Any help would be much appreciated for this!
There is problem in how divides is being called. I think
in ensures clauses you meant divides(k, a) instead of divides(a, k)
similarly for divides(b, k) and divides(gcd(a, b), k).
One way to go about this after recursive call to dividesLemma(a, b - a) is
to use postcondition of method. Here we know forall k such that k divides a and k divides b - a implies k divides gcd(a, b-a). Using this information we try to prove required postcondition (code or proof is straightforward to follow)
dividesLemma(a, b - a);
assert gcd(a, b) == gcd(a, b-a);
assert forall k : nat :: k > 0 && divides(k, a) && divides(k, b-a) ==> divides(k, gcd(a, b));
forall k : nat | k > 0 && divides(k, a) && divides(k, b) ensures divides(k, gcd(a, b)) {
var m :| a == m * k;
var n :| b == n * k;
assert (b - a) == (n - m) * k;
assume n >= m;
assert divides(k, a);
assert divides(k, b-a);
// Implied from last assert forall
assert divides(k, gcd(a, b));
}
Here I am assuming n >= m because divides requires n-m to be nat, which can proved separately.
Also second recursive call should be dividesLemma(a - b, b).
function gcd(a: nat, b: nat): nat
requires a > 0 && b > 0
{
if a == b
then a
else if a < b
then gcd(a, b-a)
else gcd(a-b, b)
}
predicate divides(a: nat, b: nat)
requires a > 0 && b > 0
{
exists k: nat :: b == k * a
}
lemma helper(a: nat, b: nat, k : nat)
requires a > 0 && b > 0 && k > 0
requires divides(k, a) && divides(k, b)
requires b >= a
ensures exists m, n :: a == m * k && b == n * k && m <= n;
{ }
lemma dividesLemma(a: nat, b: nat)
decreases a + b
requires a > 0 && b > 0
ensures gcd(a, b) > 0
ensures forall k: nat :: k > 0 && divides(k, a) && divides(k, b) ==> divides(k, gcd(a, b))
{
if (a == b){
}
else if (b > a){
dividesLemma(a, b - a);
assert gcd(a, b) == gcd(a, b-a);
assert forall k : nat :: k > 0 && divides(k, a) && divides(k, b-a) ==> divides(k, gcd(a, b));
forall k : nat | k > 0 && divides(k, a) && divides(k, b) ensures divides(k, gcd(a, b)) {
helper(a, b, k);
var m, n :| a == m * k && b == n * k && m <= n;
assert b - a == (n - m) * k;
assert divides(k, b-a);
}
}
else {
dividesLemma(a - b, b);
assert gcd(a, b) == gcd(a - b, b);
assert forall k : nat :: k > 0 && divides(k, a-b) && divides(k, b) ==> divides(k, gcd(a, b));
forall k : nat | k > 0 && divides(k, a) && divides(k, b) ensures divides(k, gcd(a, b)) {
helper(b, a, k);
var m, n :| b == m * k && a == n * k && m <= n;
assert a - b == (n - m) * k;
assert divides(k, a-b);
}
}
}

haskell TicTacToe game

I am trying to build a tic tac toe game in haskell and I am having trouble with a function haswon. The function should return True if for a given player p and the game board bs, he has already won the game, and False otherwise.
Here is the code:
Int -> [((Int,Int),Int)] -> Bool
haswon p [((a,d), x), ((b,e), y), ((c,f), z)] = (x == y && y == z && x == p) && ( ((a == b) && (b == c)) || ((d == e) && (e == f)) || ( (a == d) && (b == e) && (c == f) && (a /= b) && (b /= c)) || ( (a == f) && (c == d) && (b==e)&&(a/=b)&&(b/=c)) )
Could you please tell me how can I generalize this for an input list that is bigger than 3 elements?
For instance, the input could be : [((1,1),1), ((1,2),1), ((2,1),2), ((2,2),2), ((3,1),1), ((3,2),1), ((3,3),2)].
Thank you.
Here is the code:
Here's my take at it:
Let's define proper data types first:
data Player = Black | White deriving (Eq, Show)
data Position = Position Int Int deriving (Eq, Show)
data Move = Move { position :: Position, player :: Player } deriving (Eq, Show)
Now the actual function just counts the lines that qualify for winning
hasWon :: Player -> [Move] -> Bool
hasWon p ms = (length $ winningLines p ms) > 0
The winning lines generation is one big comprehension:
winningLines p ms = [(x,y,z) | x <- ms,
y <- ms,
z <- ms,
oneLine (position x) (position y) (position z),
samePlayer (player x) (player y) (player z),
x /= y,
y /= z,
x /= z
]
samePlayer px py pz = px == py && py == pz
oneLine (Position x1 y1) (Position x2 y2) (Position x3 y3) = sameRow || sameCol
where
sameRow = (y1 == y2 && y2 == y3)
sameCol = (x1 == x2 && x2 == x3)
And finally some testing:
moves = [
Move (Position 1 1) White,
Move (Position 2 1) White,
Move (Position 3 1) White
]
main :: IO ()
main = do
print $ hasWon White moves
print $ winningLines White moves
The solution is only using the basics, so you should be able to understand it quite easily and add your own fixes; it's still missing diagonals (easy to add), and it's counting all the lines 6 times (because it's taking all permutations into account; easy to fix with Ord instance for position and only taking a "sorted triple" into account).
Of course this is not the only way to do it; one notable alternative would be to put it into an array in-place, and then find the solution iteratively. I think the Prolog-esque declarative style just fits Haskell better, though.

Are there any languages where "A == B == C" works where A, B, and C are all non-boolean types?

Without thinking in C# I tried to compare three objects. It failed, and explained why [since (typeof("A == B") == bool) and (typeof(C) != bool) it was an invalid comparison]. Do any languages support short circuiting logic like this?
There are several languages that let you do multiple conditionals like this.
But the first I could think of was Python
Example:
a = 5
b = 5
c = 5
if(a == b == c):
print "yes"
else:
print "no"
Will print "yes" in the console.
It works with other types as well, like this:
a = ["A",1]
b = ["A",1]
c = ["A",1]
d = ["A",1]
if(a == b == c == d):
print "YES"
else:
print "NO"
Now the reason for C# (And other C like languages) doesn't support this is that they evaluate comparison expressions down to a true / false, so what your compiler sees when you do (5 == 5 == 5) is ((5 == 5) == 5) which yields: (true == 5) which invalid since you cannot compare a Boolean to an integer, you could actually write (a == b == c) if c is a Boolean, so (5 == 5 == true) would work.

Boolean negation

One of my exam questions reads:
! ( ! ( a != b) && ( b > 7 ) )
The choices:
a) (a != b) || (b < 7)
b) (a != b) || (b <= 7)
c) (a == b) || (b <= 7)
d) (a != b) && (b <= 7)
e) (a == b) && (b > 7)
Initially, I thought it would be D. This is incorrect, and I realize why. I don't understand how the logical negation operator reverses && and greater than/less than. I believe I have narrowed it down to the first two. Is there any instance > would change to <= ?
Is there any instance > would change to <= ?
Answer: every time you negate it.
Consider x > 1. The negation of this is clearly x <= 1. If you simply negate it as x < 1 then neither case covers the x == 1 case.
That being said, the given boolean ! ( ! ( a != b) && ( b > 7 ) ) can be decomposed as follows:
Given:
! ( !(a != b) && (b > 7))
Negate a != b:
! ((a == b) && (b > 7))
Distribute the !:
!(a == b) || !(b > 7)
Negate a==b:
(a != b) || !(b > 7)
Negate b>7:
(a != b) || (b <= 7)
The answer is, therefore, B.
The answer should be B. This is because the negation next to the (a != b) is evaluated first, then you distribute the outside negation to the entire proposition.
Using DeMorgan's Laws, the && will switch to ||. Similarly, != becomes ==, and > becomes <=.
!(!(a != b) && (b > 7))
!((a == b) && (b > 7))
(a != b) || (b <= 7)
! ( ! ( a != b) && ( b > 7 ) )
= ! ( (a = b) && (b > 7))
= (a != b) || (b <= 7)
answer is B.
to understand this :
! ( ! ( a != b) && ( b > 7 ) )
Lets break it into parts.
Part dummy: (a!=b)
Part X: !dummy
Part Y: (b>7)
Now !X = double negate of dummy => dummy => (a!=b)
!Y = !(b>7) => b should not be greater than 7 => b should be less than or equal to 7 => (b<=7)
Now problem left is how && becomes ||
So original question is: !( X && Y ) => should not be (X and Y) => it should be either negate of X or it should be negate of Y, because if instead of X it is ~X, the condition (X and Y) becomes false and hence !(X and Y) becomes true and hence original condition is achieved. Similarly for Y.
Firt apply the inner bracket Logical NOT (!):
!(!(a != b) && (b > 7)) becomes !((a == b) && (b > 7))
With De Morgan's Law we reverse the operators to their counterpart.
We change > to <= because the > operator does not include 7 itself or anything less, hence the <= is the only one that satisfies that condition.
Now the outer !:
When looking at truth tables (picture above), you'll notice that Logical AND (&&) and Logical OR (||) have opposite results when comparing 2 different boolean expressions (i.e. truth false, false true), hence when we apply the !, we reverse the && with ||. Finally we need to switch the == to != again.
All up, this produces
((a != b) || (b <= 7))

XOR of three values

What is the simplest way to do a three-way exclusive OR?
In other words, I have three values, and I want a statement that evaluates to true IFF only one of the three values is true.
So far, this is what I've come up with:
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
Is there something simpler to do the same thing?
Here's the proof that the above accomplishes the task:
a = true; b = true; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = true; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = false; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = true; b = false; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = true; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
a = false; b = true; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = false; c = true
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> true
a = false; b = false; c = false
((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b))
=> false
For exactly three terms, you can use this expression:
(a ^ b ^ c) && !(a && b && c)
The first part is true iff one or three of the terms are true. The second part of the expression ensures that not all three are true.
Note that the above expression does NOT generalize to more terms. A more general solution is to actually count how many terms are true, so something like this:
int trueCount =
(a ? 1 : 0) +
(b ? 1 : 0) +
(c ? 1 : 0) +
... // more terms as necessary
return (trueCount == 1); // or some range check expression etc
bool result = (a?1:0)+(b?1:0)+(c?1:0) == 1;
a^b^c is only 1 if an uneven number of variables is 1 (two '1' would cancel each other out). So you just need to check for the case "all three are 1":
result = (a^b^c) && !(a&&b&&c)
Another possibility:
a ? !b && !c : b ^ c
which happens to be 9 characters shorter than the accepted answer :)
Better yet on Python:
result = (1 if a else 0)+(1 if b else 0)+(1 if c else 0) == 1
This can be used also on if statements!
It saved my day for CLI mutually exclusive arguments through Click (everyone hates click)
You could also try (in C):
!!a + !!b + !!c == 1
Here's a general implementation that fails quickly when more than one bool is found to be true.
Usage:
XOR(a, b, c);
Code:
public static bool XOR(params bool[] bools)
{
return bools.Where(b => b).AssertCount(1);
}
public static bool AssertCount<T>(this IEnumerable<T> source, int countToAssert)
{
int count = 0;
foreach (var t in source)
{
if (++count > countToAssert) return false;
}
return count == countToAssert;
}
f= lambda{ |a| [false, false, true].permutation.to_a.uniq.include? a }
p f.call([false, true, false])
p f.call([false, true, true])
$ true
$ false
Because I can.
In C:
#include <stdbool.h>
bool array_xor(size_t array_size, bool[] array) {
int count = 0;
for (int i = 0; i < array_size && count < 2; i++) {
if (array[i]) {
count++;
}
}
return count == 1;
}