-
Notifications
You must be signed in to change notification settings - Fork 24
/
Lec_1_18.lhs
115 lines (86 loc) · 2.22 KB
/
Lec_1_18.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
\begin{code}
{-@ LIQUID "--short-names" @-}
{-@ LIQUID "--reflection" @-}
{-# LANGUAGE PartialTypeSignatures #-}
module Lec_1_18 where
import Prelude hiding (sum)
import ProofCombinators
-- 1. sum 0 == 0
-- 2. sum n >= 0
{-@ reflect sum @-}
sum :: Int -> Int
sum n = if n <= 0
then 0 -- "base" case
else n + sum (n-1) -- "recursive" case
{-@ theorem_stuff :: _ -> { v: _ | sum 2 == 3 } @-}
theorem_stuff :: _
theorem_stuff _ = sum 2
=== 2 + sum 1
=== 2 + 1 + sum 0
=== 2 + 1 + 0
=== 3
{-@ another_theorem :: _ -> { v: _ | sum 3 == 6 } @-}
another_theorem :: Int -> _
another_theorem _ = sum 3
=== 3 + sum 2
? theorem_stuff ()
=== 6
-- Theorem [MJ] : for all n. n <= sum n
{-@ theorem_MJ :: n:Int -> { n <= sum n} @-}
theorem_MJ :: Int -> Proof
theorem_MJ _ = undefined
-- for all natural numbers n: 2 * sum n == n * (n + 1)
-- forall x. Thing(x)
-- foo :: x -> { Thing x }
{-@ thm_sum :: n:Nat -> { 2 * sum n == n * (n + 1) } @-}
thm_sum :: Int -> Proof
thm_sum 0
= 2 * sum 0
=== 0 * (0 + 1)
*** QED
thm_sum k
= 2 * sum k
=== 2 * (k + (sum (k-1)))
=== 2 * k + 2 * (sum (k-1))
? thm_sum (k-1)
=== k * (k + 1)
*** QED
data Peano
= Z
| S Peano
deriving (Eq, Show)
{-@ reflect add @-}
add :: Peano -> Peano -> Peano
add Z m = m
add (S n) m = S (add n m)
{-@ thm_2_add_2_eq_4 :: _ -> { add (S (S Z)) (S (S Z)) == S (S (S (S Z))) } @-}
thm_2_add_2_eq_4 :: () -> Proof
thm_2_add_2_eq_4 _
= add (S (S Z)) (S (S Z))
=== S (add (S Z) (S (S Z)))
=== S (S (add Z (S (S Z))))
=== S (S ((S (S Z))))
=== S (S (S (S Z)))
*** QED
{-@ thm_add_Z :: p:Peano -> { add Z p == p } @-}
thm_add_Z :: Peano -> Proof
thm_add_Z p
= add Z p
=== p
*** QED
{-@ thm_Z_add :: p:Peano -> { add p Z == p } @-}
thm_Z_add :: Peano -> Proof
thm_Z_add Z
= add Z Z
=== Z
*** QED
thm_Z_add (S p)
= add (S p) Z
=== S (add p Z)
? thm_Z_add p
=== S p
*** QED
-- add Z p === p *** QED
-- >>> add (S (S Z)) (S (S Z))
-- S (S (S (S Z)))
\end{code}