{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeAbstractions #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.KnuckleDragger.Sqrt2IsIrrational where
import Prelude hiding (even, odd)
import Data.SBV
import Data.SBV.Tools.KnuckleDragger
sqrt2IsIrrational :: IO Proof
sqrt2IsIrrational :: IO Proof
sqrt2IsIrrational = KD Proof -> IO Proof
forall a. KD a -> IO a
runKD (KD Proof -> IO Proof) -> KD Proof -> IO Proof
forall a b. (a -> b) -> a -> b
$ do
let even, odd :: SInteger -> SBool
even :: SInteger -> SBool
even = (Integer
2 Integer -> SInteger -> SBool
`sDivides`)
odd :: SInteger -> SBool
odd = SBool -> SBool
sNot (SBool -> SBool) -> (SInteger -> SBool) -> SInteger -> SBool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SInteger -> SBool
even
sq :: SInteger -> SInteger
sq :: SInteger -> SInteger
sq SInteger
x = SInteger
x SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
* SInteger
x
oddSquaredIsOdd <- String
-> (Forall "a" Integer -> SBool)
-> (SInteger -> (SBool, [ProofStep SInteger]))
-> KD Proof
forall a steps.
(CalcLemma a steps, Proposition a) =>
String -> a -> steps -> KD Proof
calc String
"oddSquaredIsOdd"
(\(Forall @"a" SInteger
a) -> SInteger -> SBool
odd SInteger
a SBool -> SBool -> SBool
.=> SInteger -> SBool
odd (SInteger -> SInteger
sq SInteger
a)) ((SInteger -> (SBool, [ProofStep SInteger])) -> KD Proof)
-> (SInteger -> (SBool, [ProofStep SInteger])) -> KD Proof
forall a b. (a -> b) -> a -> b
$
\SInteger
a -> [SInteger -> SBool
odd SInteger
a] [SBool] -> [ProofStep SInteger] -> (SBool, [ProofStep SInteger])
forall a. [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
|- SInteger -> SInteger
sq SInteger
a SInteger -> SBool -> ProofStep SInteger
forall a b. ProofHint a b => a -> b -> ProofStep a
?? SInteger -> SBool
odd SInteger
a
ProofStep SInteger
-> ChainsTo (ProofStep SInteger) -> ChainsTo (ProofStep SInteger)
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SInteger -> SInteger
sq (SInteger
2 SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
* ((SInteger
aSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
-SInteger
1) SInteger -> SInteger -> SInteger
`sEDiv` SInteger
2) SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
1)
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: [ProofStep SInteger]
ChainsTo SInteger
forall a. [ProofStep a]
qed
squareEvenImpliesEven <- lemma "squareEvenImpliesEven"
(\(Forall @"a" SInteger
a) -> SInteger -> SBool
even (SInteger -> SInteger
sq SInteger
a) SBool -> SBool -> SBool
.=> SInteger -> SBool
even SInteger
a)
[oddSquaredIsOdd]
evenSquaredIsMult4 <- calc "evenSquaredIsMult4"
(\(Forall @"a" SInteger
a) -> SInteger -> SBool
even SInteger
a SBool -> SBool -> SBool
.=> Integer
4 Integer -> SInteger -> SBool
`sDivides` SInteger -> SInteger
sq SInteger
a) $
\SInteger
a -> [SInteger -> SBool
even SInteger
a] [SBool] -> [ProofStep SInteger] -> (SBool, [ProofStep SInteger])
forall a. [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
|- SInteger -> SInteger
sq SInteger
a SInteger -> SBool -> ProofStep SInteger
forall a b. ProofHint a b => a -> b -> ProofStep a
?? SInteger -> SBool
even SInteger
a
ProofStep SInteger
-> ChainsTo (ProofStep SInteger) -> ChainsTo (ProofStep SInteger)
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SInteger -> SInteger
sq (SInteger
2 SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
* (SInteger
a SInteger -> SInteger -> SInteger
`sEDiv` SInteger
2))
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: [ProofStep SInteger]
ChainsTo SInteger
forall a. [ProofStep a]
qed
let coPrime :: SInteger -> SInteger -> SBool
coPrime SInteger
x SInteger
y = (Forall "z" Integer -> SBool) -> SBool
forall a. QuantifiedBool a => a -> SBool
quantifiedBool (\(Forall @"z" SInteger
z) -> (SInteger
x SInteger -> SInteger -> SInteger
`sEMod` SInteger
z SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
0 SBool -> SBool -> SBool
.&& SInteger
y SInteger -> SInteger -> SInteger
`sEMod` SInteger
z SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
0) SBool -> SBool -> SBool
.=> SInteger
z SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
1)
lemma "sqrt2IsIrrational"
(\(Forall @"a" SInteger
a) (Forall @"b" SInteger
b) -> (SInteger -> SInteger
sq SInteger
a SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
2 SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
* SInteger -> SInteger
sq SInteger
b) SBool -> SBool -> SBool
.=> SBool -> SBool
sNot (SInteger -> SInteger -> SBool
coPrime SInteger
a SInteger
b))
[squareEvenImpliesEven, evenSquaredIsMult4]