Skip to content

Commit a723bb1

Browse files
authored
Merge branch 'develop' into adinapoli/polish-docs
2 parents abe8bde + 1bd2a42 commit a723bb1

File tree

20 files changed

+2365
-20
lines changed

20 files changed

+2365
-20
lines changed

Diff for: benchmarks/cse230/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 Dr. Kat
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: benchmarks/cse230/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Retrieved from: https://github.com/ucsd-progsys/230-wi19-web/

Diff for: benchmarks/cse230/src/Week10/Axiomatic.hs

+364
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
{-@ LIQUID "--reflection" @-}
2+
{-@ LIQUID "--ple" @-}
3+
{-@ LIQUID "--diff" @-}
4+
{- LIQUID "--short-names" @-}
5+
{-@ infixr ++ @-} -- TODO: Silly to have to rewrite this annotation!
6+
{-@ infixr <~ @-} -- TODO: Silly to have to rewrite this annotation!
7+
8+
--------------------------------------------------------------------------------
9+
-- | Inspired by
10+
-- http://flint.cs.yale.edu/cs428/coq/sf/Hoare.html
11+
-- http://flint.cs.yale.edu/cs428/coq/sf/Hoare2.html
12+
--------------------------------------------------------------------------------
13+
14+
{-# LANGUAGE GADTs #-}
15+
16+
module Axiomatic where
17+
18+
import Prelude hiding ((++))
19+
import ProofCombinators
20+
import qualified State as S
21+
import Expressions
22+
import Imp
23+
import BigStep hiding (And)
24+
25+
--------------------------------------------------------------------------------
26+
{- | A Floyd-Hoare triple is of the form
27+
28+
{ P } c { Q }
29+
30+
where
31+
32+
- `P` and `Q` are assertions (think `BExp`) and
33+
- `c` is a command (think `Com`)
34+
35+
A Floyd-Hoare triple states that
36+
37+
IF
38+
39+
* The program `c` is starts at a state where the *precondition* `P` is True, and
40+
* The program finishes execution
41+
42+
THEN
43+
44+
* At the final state, the *postcondition* `Q` will also evaluate to True.
45+
46+
-}
47+
48+
{- | Lets paraphrase the following Hoare triples in English.
49+
50+
1) {True} c {X = 5}
51+
52+
2) {X = m} c {X = m + 5}
53+
54+
3) {X <= Y} c {Y <= X}
55+
56+
4) {True} c {False}
57+
58+
-}
59+
60+
61+
--------------------------------------------------------------------------------
62+
-- | The type `Assertion` formalizes the type for the
63+
-- assertions (i.e. pre- and post-conditions) `P`, `Q`
64+
-- appearing in the triples {P} c {Q}
65+
66+
type Assertion = BExp
67+
68+
--------------------------------------------------------------------------------
69+
70+
--------------------------------------------------------------------------------
71+
{- | Legitimate Triples
72+
--------------------------------------------------------------------------------
73+
74+
Which of the following triples are "legit" i.e., the claimed relation between
75+
`pre`condition` `P`, `com`mand `C`, and `post`condition `Q` is true?
76+
77+
1) {True}
78+
X <~ 5
79+
{X = 5}
80+
81+
2) {X = 2}
82+
X <~ X + 1
83+
{X = 3}
84+
85+
3) {True}
86+
X <~ 5;
87+
Y <~ 0
88+
{X = 5}
89+
90+
4) {True}
91+
X <~ 5;
92+
Y <~ X
93+
{Y = 5}
94+
95+
5) {X = 2 && X = 3}
96+
X <~ 5
97+
{X = 0}
98+
99+
6) {True}
100+
SKIP
101+
{False}
102+
103+
7) {False}
104+
SKIP
105+
{True}
106+
107+
8) {True}
108+
WHILE True DO
109+
SKIP
110+
{False}
111+
112+
9) {X = 0}
113+
WHILE X <= 0 DO
114+
X <~ X + 1
115+
{X = 1}
116+
117+
10) {X = 1}
118+
WHILE not (X <= 0) DO
119+
X <~ X + 1
120+
{X = 100}
121+
-}
122+
123+
--------------------------------------------------------------------------------
124+
-- | `Legit` formalizes the notion of when a Floyd-Hoare triple is legitimate
125+
--------------------------------------------------------------------------------
126+
{-@ type Legit P C Q = s:{State | bval P s}
127+
-> s':_ -> Prop (BStep C s s')
128+
-> {bval Q s'}
129+
@-}
130+
type Legit = State -> State -> BStep -> Proof
131+
132+
-- | {True} X <~ 5 {X = 5} ---------------------------------------------------
133+
134+
{-@ leg1 :: Legit tt (Assign {"x"} (N 5)) (Equal (V {"x"}) (N 5)) @-}
135+
leg1 :: Legit
136+
leg1 s s' (BAssign {})
137+
= S.lemma_get_set "x" 5 s
138+
139+
140+
-- | {True} X <~ 5; y <- X {X = 5} -------------------------------------------
141+
142+
{-@ leg3 :: Legit tt (Seq (Assign {"x"} (N 5)) (Assign {"y"} (V {"x"}))) (Equal (V {"y"}) (N 5)) @-}
143+
leg3 :: Legit
144+
leg3 s s' (BSeq _ _ _ smid _ (BAssign {}) (BAssign {}))
145+
= S.lemma_get_set "x" 5 s &&& S.lemma_get_set "y" 5 smid
146+
147+
148+
-- | {False} X <~ 5 {X = 0} --------------------------------------------------
149+
150+
{-@ leg5 :: Legit ff (Assign {"x"} (N 5)) (Equal (V {"x"}) (N 22)) @-}
151+
leg5 :: Legit
152+
leg5 s s' _ = ()
153+
154+
155+
--------------------------------------------------------------------------------
156+
-- | Two simple facts about Floyd-Hoare Triples --------------------------------
157+
--------------------------------------------------------------------------------
158+
159+
{-@ lem_post_true :: p:_ -> c:_ -> Legit p c tt @-}
160+
lem_post_true :: Assertion -> Com -> Legit
161+
lem_post_true p c = \s s' c_s_s' -> ()
162+
163+
{-@ lem_pre_false :: c:_ -> q:_ -> Legit ff c q @-}
164+
lem_pre_false :: Com -> Assertion -> Legit
165+
lem_pre_false c q = \s s' c_s_s' -> ()
166+
167+
168+
-- | Assignment
169+
170+
-- { Y = 1 } X <~ Y { X = 1 }
171+
172+
-- { X + Y = 1 } X <~ X + Y { X = 1 }
173+
174+
-- { a = 1 } X <~ a { X = 1 }
175+
176+
177+
{- | Lets fill in the blanks
178+
179+
{ ??? }
180+
x <~ 3
181+
{ x == 3 }
182+
183+
{ ??? }
184+
x <~ x + 1
185+
{ x <= 5 }
186+
187+
{ ??? }
188+
x <~ y + 1
189+
{ 0 <= x && x <= 5 }
190+
191+
-}
192+
193+
194+
{- | To conclude that an arbitrary postcondition `Q` holds after
195+
`x <~ a`, we need to assume that Q holds before `x <~ a`
196+
but with all occurrences of `x` replaced by `a` in `Q`
197+
198+
Lets revisit the example above:
199+
200+
{ ??? }
201+
x <~ 3
202+
{ x == 3 }
203+
204+
{ ??? }
205+
x <~ x + 1
206+
{ x <= 5 }
207+
208+
{ ??? }
209+
x <~ y + 1
210+
{ 0 <= x && x <= 5 }
211+
212+
-}
213+
214+
--------------------------------------------------------------------------------
215+
-- | `Valid`ity of an assertion
216+
--------------------------------------------------------------------------------
217+
218+
219+
-- forall s. bval P s == True
220+
{-@ type Valid P = s:State -> { v: Proof | bval P s } @-}
221+
type Valid = State -> Proof
222+
223+
-- x >= 0 || x < 0
224+
225+
{-@ checkValid :: p:_ -> Valid p -> () @-}
226+
checkValid :: Assertion -> Valid -> ()
227+
checkValid p v = ()
228+
229+
-- x <= 0
230+
ex0 = checkValid (e0 `bImp` e1) (\_ -> ())
231+
where
232+
e0 = (V "x") `Leq` (N 0)
233+
e1 = ((V "x") `Minus` (N 1)) `Leq` (N 0)
234+
235+
-- x <= 0 => x - 1 <= 0
236+
-- e1 = e0 `bImp` ((V "x" `Minus` N 1) `Leq` (N 0))
237+
238+
--------------------------------------------------------------------------------
239+
-- | When does an assertion `Imply` another
240+
--------------------------------------------------------------------------------
241+
242+
{-@ type Imply P Q = Valid (bImp P Q) @-}
243+
244+
-- 10 <= x => 5 <= x
245+
{-@ v1 :: _ -> Imply (Leq (N 10) (V {"x"})) (Leq (N 5) (V {"x"})) @-}
246+
v1 :: a -> Valid
247+
v1 _ = \_ -> ()
248+
249+
-- (0 < x && 0 < y) ===> (0 < x + y)
250+
{-@ v2 :: _ -> Imply (bAnd (Leq (N 0) (V {"x"})) (Leq (N 0) (V {"y"})))
251+
(Leq (N 0) (Plus (V {"x"}) (V {"y"})))
252+
@-}
253+
v2 :: a -> Valid
254+
v2 _ = \_ -> ()
255+
256+
--------------------------------------------------------------------------------
257+
-- | The Floyd-Hoare proof system
258+
--------------------------------------------------------------------------------
259+
260+
data FHP where
261+
FH :: Assertion -> Com -> Assertion -> FHP
262+
263+
data FH where
264+
FHSkip :: Assertion -> FH
265+
FHAssign :: Assertion -> Vname -> AExp -> FH
266+
FHSeq :: Assertion -> Com -> Assertion -> Com -> Assertion -> FH -> FH -> FH
267+
FHIf :: Assertion -> Assertion -> BExp -> Com -> Com -> FH -> FH -> FH
268+
FHWhile :: Assertion -> BExp -> Com -> FH -> FH
269+
FHConPre :: Assertion -> Assertion -> Assertion -> Com -> Valid -> FH -> FH
270+
FHConPost :: Assertion -> Assertion -> Assertion -> Com -> FH -> Valid -> FH
271+
272+
{-@ data FH where
273+
FHSkip :: p:_
274+
-> Prop (FH p Skip p)
275+
| FHAssign :: q:_ -> x:_ -> a:_
276+
-> Prop (FH (bsubst x a q) (Assign x a) q)
277+
| FHSeq :: p:_ -> c1:_ -> q:_ -> c2:_ -> r:_
278+
-> Prop (FH p c1 q)
279+
-> Prop (FH q c2 r)
280+
-> Prop (FH p (Seq c1 c2) r)
281+
| FHIf :: p:_ -> q:_ -> b:_ -> c1:_ -> c2:_
282+
-> Prop (FH (bAnd p b) c1 q)
283+
-> Prop (FH (bAnd p (Not b)) c2 q)
284+
-> Prop (FH p (If b c1 c2) q)
285+
| FHWhile :: inv:_ -> b:_ -> c:_
286+
-> Prop (FH (bAnd inv b) c inv)
287+
-> Prop (FH inv (While b c) (bAnd inv (Not b)))
288+
| FHConPre :: p':_ -> p:_ -> q:_ -> c:_
289+
-> Imply p' p
290+
-> Prop (FH p c q)
291+
-> Prop (FH p' c q)
292+
| FHConPost :: p:_ -> q:_ -> q':_ -> c:_
293+
-> Prop (FH p c q)
294+
-> Imply q q'
295+
-> Prop (FH p c q')
296+
@-}
297+
298+
--------------------------------------------------------------------------------
299+
-- | THEOREM: Soundness of Floyd-Hoare Logic
300+
--------------------------------------------------------------------------------
301+
-- thm_fh_legit :: p:_ -> c:_ -> q:_ -> Prop (FH p c q) -> Legit p c q
302+
303+
-- thm_legit_fh :: p:_ -> c:_ -> q:_ -> Legit p c q -> Prop (FH p c q)
304+
305+
306+
--------------------------------------------------------------------------------
307+
-- | Making FH Algorithmic: Verification Conditions
308+
--------------------------------------------------------------------------------
309+
data ICom
310+
= ISkip -- skip
311+
| IAssign Vname AExp -- x := a
312+
| ISeq ICom ICom -- c1; c2
313+
| IIf BExp ICom ICom -- if b then c1 else c2
314+
| IWhile Assertion BExp ICom -- while {I} b c
315+
deriving (Show)
316+
317+
{-@ reflect pre @-}
318+
pre :: ICom -> Assertion -> Assertion
319+
pre ISkip q = q
320+
pre (IAssign x a) q = bsubst x a q
321+
pre (ISeq c1 c2) q = pre c1 (pre c2 q)
322+
pre (IIf b c1 c2) q = bIte b (pre c1 q) (pre c2 q)
323+
pre (IWhile i _ _) _ = i
324+
325+
326+
327+
328+
{-@ reflect vc @-}
329+
vc :: ICom -> Assertion -> Assertion
330+
vc ISkip _ = tt
331+
vc (IAssign {}) _ = tt
332+
vc (ISeq c1 c2) q = (vc c1 (pre c2 q)) `bAnd` (vc c2 q)
333+
vc (IIf _ c1 c2) q = (vc c1 q) `bAnd` (vc c2 q)
334+
vc (IWhile i b c) q = ((bAnd i b) `bImp` (pre c i)) `bAnd` -- { i && b} c { i }
335+
((bAnd i (Not b)) `bImp` q ) `bAnd` -- { i & ~b} => Q
336+
vc c i
337+
338+
{-@ reflect erase @-}
339+
erase :: ICom -> Com
340+
erase ISkip = Skip
341+
erase (IAssign x a) = Assign x a
342+
erase (ISeq c1 c2) = Seq (erase c1) (erase c2)
343+
erase (IIf b c1 c2) = If b (erase c1) (erase c2)
344+
erase (IWhile _ b c) = While b (erase c)
345+
346+
-----------------------------------------------------------------------------------
347+
-- | THEOREM: Soundness of VC
348+
-----------------------------------------------------------------------------------
349+
-- thm_vc :: c:_ -> q:_ -> Valid (vc c q) -> Legit (pre c q) (erase c) q
350+
351+
-----------------------------------------------------------------------------------
352+
-- | Extending the above to triples [HW]
353+
-----------------------------------------------------------------------------------
354+
355+
{-@ reflect vc' @-}
356+
vc' :: Assertion -> ICom -> Assertion -> Assertion
357+
vc' p c q = bAnd (bImp p (pre c q)) (vc c q)
358+
359+
-----------------------------------------------------------------------------------
360+
-- | THEOREM: Soundness of VC'
361+
-----------------------------------------------------------------------------------
362+
-- thm_vc' :: p:_ -> c:_ -> q:_ -> Valid (vc' p c q) -> Legit p (erase c) q
363+
364+

0 commit comments

Comments
 (0)