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);
}
}
}
Related
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.
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.
I'm trying to make an Idris function of type (j : Nat) -> {auto p : So (j < n)} -> Fin n to convert a Nat into a Fin n. To get the Z case to work (and output FZ), I'm trying to prove that a proof of 0 < n is sufficient to be able to make FZ : Fin n. But I can't work out how to do this.
I'm open to making a completely different function, as long as it can convert Nat values into Fin n values (where they exist). My goal is to have some other function that can convert any Nat into a Mod n value, so that, for example, 15 : Nat is mapped to 3 : Mod 4. My Mod type currently has a single constructor, mkMod : Fin n -> Mod n.
After learning about LT : Nat -> Nat -> Type, I took a different approach. I started with the declaration:
natToFin : (j : Nat) -> {auto p : j `LT` n} -> Fin n
natToFin {n} j {p} = ?natToFin_rhs_1
. Case-splitting on n, then on p in the n = Z case resulted in:
natToFin : (j : Nat) -> {auto p : j `LT` n} -> Fin n
natToFin {n = (S k)} j {p = p} = ?natToFin_rhs_2
, which is essentially the proof I was asking for. From there, I case-split on j and filled the zero case, leaving:
natToFin : (j : Nat) -> {auto p : j `LT` n} -> Fin n
natToFin {n = (S k)} Z = FZ
natToFin {n = (S k)} (S j) {p = p} = ?natToFin_rhs_3
. I wanted to fill ?natToFin_rhs_3 with FS (natToFin j), but the type checker wasn't letting me. However, after a case split on p, it was fine:
natToFin : (j : Nat) -> {auto p : j `LT` n} -> Fin n
natToFin {n = (S k)} Z = FZ
natToFin {n = (S k)} (S j) {p = (LTESucc x)} = FS (natToFin j)
Finally, I added total, and it all checked out.
The only problem now is that Idris can't seem to find LT proofs automatically. This is what happens:
λΠ> the (Fin 6) (natToFin 2)
When elaborating argument p to function mod2.natToFin:
Can't solve goal
LT (fromInteger 2) (fromInteger 6)
Is there any way to fix that?
A && B || C && D
(A && B) || (C && D)
Are both boolean logic equal in C++? I am confused.
Whether or not they're equal depends entirely on how you define your operator precedence. If && takes precedence over ||, then yes. Otherwise, no.
In the most programming languages you'll find that operator && is of higher priority than ||.
So for example in Java, C#, C, C++, Python, Ruby, etc.
A && B || C && D
is equivalent to
(A && B) || (C && D)
You can even copy-paste the code:
#include <iostream>
using namespace std;
int main() {
bool A = false;
bool B = false;
bool C = true;
bool D = true;
for(int i = 0; i < 2; ++i) {
A = (i == 0);
for(int j = 0; j < 2; ++j) {
B = (j == 0);
for(int k = 0; k < 2; ++k) {
C = (k == 0);
for(int l = 0; l < 2; ++l) {
D = (l == 0);
cout << A << " " << B << " " << C << " " << D << " -> ";
cout << ((A && B || C && D) == ((A && B) || (C && D))) << endl;
}
}
}
}
return 0;
}
to Ideone to find out for yourself. In C++ for example the output is:
1 1 1 1 -> 1
1 1 1 0 -> 1
1 1 0 1 -> 1
1 1 0 0 -> 1
1 0 1 1 -> 1
1 0 1 0 -> 1
1 0 0 1 -> 1
1 0 0 0 -> 1
0 1 1 1 -> 1
0 1 1 0 -> 1
0 1 0 1 -> 1
0 1 0 0 -> 1
0 0 1 1 -> 1
0 0 1 0 -> 1
0 0 0 1 -> 1
0 0 0 0 -> 1
So the ((A && B || C && D) == ((A && B) || (C && D))) is a tautology.
While the final answer goes to the specifics of the C++ language you're asking about, here's some food for thought on why (and possibly how) to remember:
Conjunction (AND, &&) is often associated with multiplication, while disjunction (OR, ||) is often associated with addition (and we generally know the precedence of multiplication over addition).
Here's a quote from http://www.ocf.berkeley.edu/~fricke/projects/quinto/dnf.html:
... As a practical matter, we usually associate conjunction with
multiplication and disjunction with addition. Indeed, if we identify
true with 1 and false with 0, then {0,1} coupled with the usual
definitions of addition and multiplication over the Galois field of
size 2 (eg, arithmetic modulo 2), then addition (+) and disjunction
(or) really are the same, as are multiplication and conjunction (and).
...
Speaking in rather general terms, the computer languages tend to honor the precedence of multiplicative operators over additive operators.
(Further, these associations, e.g. between operators in logic and in algebra reoccur in other areas, such as type systems. For an interesting exposition of that, see http://blog.lab49.com/archives/3011 on the notion of Algebraic Type Systems.)
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;
}