Download presentation
Presentation is loading. Please wait.
1
A Verification Condition Visualizer
Andrew Ireland and Madiha Jami School of Mathematical & Computer Sciences Heriot-Watt University Edinburgh Nov-18 CIAO DFKI Bremen
2
Motivations Nov-18 CIAO DFKI Bremen
3
Overview If pictures help develop intuitions about data structures, why not exploit them more? Engage students and broaden the accessibility of formal verification technologies Productivity gains within industrial scale formal verification, i.e. Help decide if a proof effort is worth while or not If yes then provides guidance as to how the proof might proceed If no then provides guidance as to where bugs and inconsistences lie Focus on arrays and a prototype tool (MSc Project) Outline work in progress and future vision Funded by EPSRC Platform Grant EP/J001058 Nov-18 CIAO DFKI Bremen
4
Basic Building Blocks Element: Segment: .… Concrete Arbitrary Index i
Property P .… i P Nov-18 CIAO DFKI Bremen
5
Properties & Relations
… … … P … … … R 28/11/2018 CIAO DFKI Bremen
6
Updates i A(i):= E A(i):= A(j) t:= A(i); A(i):=A(j); A(j):= t E i j .… …. .… i j .… …. .… update(update(A, [i], element(A, [j])), [j], element(A, [i])) Nov-18 CIAO DFKI Bremen
7
Polish Flag --# pre (for all I in IndexRange => (Flag(I)=Red or Flag(I)=White)) --# post for some P in Integer range (Flag'First) .. (Flag'Last+1) => --# ((for all Q in Integer range Flag'First..(P-1) => (Flag(Q)=Red)) and --# (for all R in Integer range P..Flag'Last => (Flag(R)=White))); Nov-18 CIAO DFKI Bremen
8
Polish Flag …. .… …. red white f l red or white f P-1 P l Nov-18
.… …. red white Nov-18 CIAO DFKI Bremen
9
SPARK Code loop … if else J:=J-1; T:=Flag(I);
Flag(I):=Flag(J); Flag(J):=T; end if; end loop; SPARK Code procedure Partition_Section(Flag: in out ArrayOfColours) is subtype JustBiggerRange is Integer range Flag'First .. Flag'Last+1; I: JustBiggerRange; J: JustBiggerRange; T: Colour; begin I:=Flag'First; J:=Flag'Last+1; loop --# assert Flag'First<=I and --# J<=(Flag'Last+1) and --# I<=J and --# (for all Q in Integer range Flag'First..(I-1) => (Flag(Q)=Red)) and --# (for all R in Integer range J..Flag'Last => (Flag(R)=White)); exit when I=J; if Flag(I)=Red then I:=I+1; else J:=J-1;T:=Flag(I); Flag(I):=Flag(J); Flag(J):=T; end if; end loop; end Partition_Section Nov-18 CIAO DFKI Bremen
10
procedure_partition_section_5. H1: indexrange__first <= i .
H2: j <= indexrange__last + 1 . H3: i <= j . H4: for_all (q_: integer, ((q_ >= indexrange__first) and ( q_ <= i - 1)) -> (element(flag, [q_]) = red)) . H5: for_all (r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . H6: for_all (i___1: integer, ((i___1 >= indexrange__first) and ( i___1 <= indexrange__last)) -> ((element(flag, [ i___1]) >= colour__first) and (element(flag, [ i___1]) <= colour__last))) . H7: for_all (i_: integer, ((i_ >= indexrange__first) and ( i_ <= indexrange__last)) -> ((element(flag~, [i_]) = red) or (element(flag~, [i_]) = white))) . H8: not (i = j) . H9: j >= pointerrange__first . H10: j <= pointerrange__last . H11: i >= pointerrange__first . H12: i <= pointerrange__last . H13: i >= indexrange__first . H14: i <= indexrange__last . H15: not (element(flag, [i]) = red) . H16: j - 1 >= justbiggerrange__first . H17: j - 1 <= justbiggerrange__last . H18: element(flag, [i]) >= colour__first . H19: element(flag, [i]) <= colour__last . H20: i >= indexrange__first . H21: i <= indexrange__last . H22: element(flag, [j - 1]) >= colour__first . H23: element(flag, [j - 1]) <= colour__last . H24: j - 1 >= indexrange__first . H25: j - 1 <= indexrange__last . H26: i >= indexrange__first . H27: i <= indexrange__last . H28: element(flag, [i]) >= colour__first . H29: element(flag, [i]) <= colour__last . H30: j - 1 >= indexrange__first . H31: j - 1 <= indexrange__last . -> C1: indexrange__first <= i . C2: j - 1 <= indexrange__last + 1 . C3: i <= j - 1 . C4: for_all (q_: integer, ((q_ >= indexrange__first) and ( q_ <= i - 1)) -> (element(update(update(flag, [i], element( flag, [j - 1])), [j - 1], element(flag, [i])), [ q_]) = red)) . C5: for_all (r_: integer, ((r_ >= j - 1) and (r_ <= indexrange__last)) -> (element(update(update( flag, [i], element(flag, [j - 1])), [j - 1], element( flag, [i])), [r_]) = white)) . C6: for_all (i___1: integer, ((i___1 >= indexrange__first) and ( i___1 <= indexrange__last)) -> ((element(update(update( flag, [i])), [i___1]) >= colour__first) and (element(update(update( flag, [i])), [i___1]) <= colour__last))) . C7: for_all (i_: integer, ((i_ >= indexrange__first) and ( Nov-18 CIAO DFKI Bremen
11
Polish Flag [ loop-else ]
procedure_partition_section_5 . ... H3: i <= j . H4: for_all(q_: integer, ((q_ >= indexrange__first) and (q_ <= i - 1)) -> (element(flag, [q_]) = red)) . H5: for_all(r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . H12: not (i = j) . H17: not (element(flag, [i]) = red) . … -> C4: for_all(q_: integer, ((q_ >= indexrange__first) and (q_ <= i - 1)) -> (element(update(update(flag, [i], element(flag, [j - 1])), [j - 1], element(flag, [i])), [ q_]) = red)) . C5: for_all(r_: integer, ((r_ >= j - 1) and (r_ <= indexrange__last)) -> (element(update(update( flag, [i], element(flag, [j - 1])), [j - 1], element(flag, [i])), [r_]) = white)) . Nov-18 CIAO DFKI Bremen
12
Polish Flag [ loop-else ]
j l .… …. .… Given: red white white f i j-1 l .… …. .… Goal: red white Nov-18 CIAO DFKI Bremen
13
Polish Flag [ post-loop ]
procedure_partition_section_14. H1: indexrange__first <= i . H2: j <= indexrange__last + 1 . … H4: for_all (q_: integer, ((q_ >= indexrange__first) and (q_ <= i - 1)) -> (element(flag, [q_]) = red)) . H5: for_all (r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . H8: i = j . -> C1: for_some (p_: integer, ((p_ >= indexrange__first) and ( p_ <= indexrange__last + 1)) and (( for_all (q_: integer, ((q_ >= indexrange__first) and (q_ <= p_ - 1)) -> (element( flag, [q_]) = red))) and ( for_all (r_: integer, (( r_ >= p_) and (r_ <= indexrange__last)) -> (element( flag, [r_]) = white))))) . Nov-18 CIAO DFKI Bremen
14
Polish Flag [ post-loop ]
j l .… …. Given: red white f P-1 P l Goal: .… …. red white Nov-18 CIAO DFKI Bremen
15
Revised SPARK Code procedure Partition_Section(Flag: in out ArrayOfColours) is subtype JustBiggerRange is Integer range Flag'First .. Flag'Last+1; I: JustBiggerRange; J: JustBiggerRange; T: Colour; begin I:=Flag'First; J:=Flag'Last+1; loop --# assert Flag'First<=I and --# J<=(Flag'Last+1) and --# I<=J and --# (for all Q in Integer range Flag'First..(I+1) => (Flag(Q)=Red)) and --# (for all R in Integer range J..Flag'Last => (Flag(R)=White)); exit when I=J; if Flag(I)=White then J:=J-1;T:=Flag(I); Flag(I):=Flag(J); Flag(J):=T; I:=I+1; else end if; end loop; end Partition_Section Nov-18 CIAO DFKI Bremen
16
Polish Flag [ loop-then ] Revisited
procedure_partition_section_4. … H3: i <= j . H4: for_all(q_: integer, ((q_ >= indexrange__first) and ( q_ <= i + 1)) -> (element(flag, [q_]) = red)) . H12: not (i = j) . H17: element(flag, [i]) = white . -> C4: for_all(q_: integer, ((q_ >= indexrange__first) and ( q_ <= i + 1)) -> (element(update(update(flag, [i], element( flag, [j - 1])), [j - 1], element(flag, [i])), [q_]) = red)) . ? Nov-18 CIAO DFKI Bremen
17
Polish Flag [ loop-then ] Revisited
j l .… …. .… Given: red white white contradiction f i i+1 j-1 j l .… …. . … Goal: red white Nov-18 CIAO DFKI Bremen
18
Polish Flag [ loop-else ] Revisited
procedure_partition_section_5. … H3: i <= j . H4: for_all(q_: integer, ((q_ >= indexrange__first) and ( q_ <= i + 1)) -> (element(flag, [q_]) = red)) . H12: not (i = j) . H17: not (element(flag, [i]) = white) . -> C4: for_all(q_: integer, ((q_ >= indexrange__first) and ( q_ <= i )) -> (element(flag, [q_]) = red)) . ? Nov-18 CIAO DFKI Bremen
19
Polish Flag [ loop-else ] Revisited
j l .… …. .… Given: red white red f i i+1 i+2 j l Goal: .… …. .… red white unprovable Nov-18 CIAO DFKI Bremen
20
Polish Flag [ post-loop ] Revisited
procedure_partition_section_12. … H3: i <= j . H4: for_all(q_: integer, ((q_ >= indexrange__first) and (q_ <= i + 1)) -> (element(flag, [q_]) = red)) . H5: for_all(r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . H12: i = j . -> C1: for_some(p_: integer, ((p_ >= indexrange__first) and ( p_ <= indexrange__last + 1)) and ((for_all(q_: integer, ((q_ >= indexrange__first) and (q_ <= p_ - 1)) -> (element( flag, [q_]) = red))) and (for_all(r_: integer, (( r_ >= p_) and (r_ <= indexrange__last)) -> (element( flag, [r_]) = white))))) . ? Nov-18 CIAO DFKI Bremen
21
Polish Flag [ post-loop ] Revisited
j i+1 l .… …. Given: white red contradiction f P-1 P l Goal: .… …. red white Nov-18 CIAO DFKI Bremen
22
Core Algorithm Identification of the arrays that are explicitly referenced within the given hypotheses and conclusions Extraction of properties and relations of the elements and segments that are contained within the identified arrays, including constraints on index variables and upper and lower bounds Ordering the elements and segments that are explicitly identified above, this may involve elementary reasoning with regards to the constraints extracted for index variables Positioning the elements and segments, i.e. determining if segments (and elements) are adjoining non-adjoining overlapping Note: Implicit gaps and overlaps are calculated, i.e. either a fixed number of consecutive elements or an arbitrary segment Nov-18 CIAO DFKI Bremen
23
Auto-VCV Nov-18 CIAO DFKI Bremen
24
Polish Flag [ loop-else ]
Nov-18 CIAO DFKI Bremen
25
Polish Flag [ loop-then ] Revisited
Nov-18 CIAO DFKI Bremen
26
Bubble Max subtype Index_Type is Integer range 1 .. 9;
type Array_Type is array (Index_Type) of Integer; ... procedure Bubble_Max(Table: in out Array_Type) is R: Index_Type; T: Integer; begin R:= 1; loop --# assert (for all I in Integer range Table'First .. (R-1) => (Table(I) <= Table(R))); exit when R = Index_Type'Last; R:=R+1; if Table(R-1) > Table(R) then T:= Table(R); Table(R):= Table(R-1); Table(R-1):= T; end if; end loop; end Bubble_Max; Nov-18 CIAO DFKI Bremen
27
Bubble Max [ true branch ]
procedure_bubble_max_3. H1: for_all(i_: integer, ((i_ >= index_type__first) and (i_ <= r - 1)) -> (element(table, [i_]) <= element(table, [r]))) . ... H18: element(table, [r ]) > element(table, [r + 1]) . -> C1: for_all(i_: integer, ((i_ >= index_type__first) and (i_ <= r )) -> (element(update(update( table, [r + 1], element(table, [r ])), [r ], element( table, [r + 1])), [i_]) <= element(update(update(table, [r + 1], element(table, [r ])), [r ], element(table, [r + 1])), [r + 1]))) . Nov-18 CIAO DFKI Bremen
28
Bubble Max [ true branch ]
Nov-18 CIAO DFKI Bremen
29
Future Work Relations between pictures, e.g. output is a permutation of the input Deal with user definitions, i.e. proof functions Array of arrays, arrays of records, records of … Represent buggy cases as concrete pictures Industrial scale examples, e.g. 90+ hypotheses, arrays of records with arrays, … Working with BAE Systems (Warton, UK) – advanced avionics control systems written in SPARK – productivity gain “would reduce time spent deciding if a VC is provable” Nov-18 CIAO DFKI Bremen
30
Future Work Possibly target Boogie – the generic VCG would enable the ideas to be applied to many more programming languages Pointer based programs - separation logic provides a natural formalism for extracting pictures From verification to synthesis – interactively evolve formal invariants via a programmer’s data structure sketches? Proof by pictures? Nov-18 CIAO DFKI Bremen
31
Conclusion Pictures help in developing programming and proof intuitions about data structures Verification tools that include pictorial representations could, where appropriate, help: engage the next generation of software verification researchers broaden the accessibility and productivity of software verification technologies “A picture is worth a thousand words” “A formula is worth a thousand pictures” The truth lies somewhere between the two Nov-18 CIAO DFKI Bremen
32
Extra Stuff … Nov-18 CIAO DFKI Bremen
33
SPARK Code loop … if Flag(I)=Red then I:=I+1; else end if; end loop;
procedure Partition_Section(Flag: in out ArrayOfColours) is subtype JustBiggerRange is Integer range Flag'First .. Flag'Last+1; I: JustBiggerRange; J: JustBiggerRange; T: Colour; begin I:=Flag'First; J:=Flag'Last+1; loop --# assert Flag'First<=I and --# J<=(Flag'Last+1) and --# I<=J and --# (for all Q in Integer range Flag'First..(I-1) => (Flag(Q)=Red)) and --# (for all R in Integer range J..Flag'Last => (Flag(R)=White)); exit when I=J; if Flag(I)=Red then I:=I+1; else J:=J-1;T:=Flag(I); Flag(I):=Flag(J); Flag(J):=T; end if; end loop; end Partition_Section Nov-18 CIAO DFKI Bremen
34
For path(s) from assertion of line 94 to assertion of line 94:
procedure_partition_section_4. H1: indexrange__first <= i . H2: j <= indexrange__last + 1 . H3: i <= j . H4: for_all (q_: integer, ((q_ >= indexrange__first) and ( q_ <= i - 1)) -> (element(flag, [q_]) = red)) . H5: for_all (r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . H6: for_all (i___1: integer, ((i___1 >= indexrange__first) and ( i___1 <= indexrange__last)) -> ((element(flag, [ i___1]) >= colour__first) and (element(flag, [ i___1]) <= colour__last))) . H7: for_all (i_: integer, ((i_ >= indexrange__first) and ( i_ <= indexrange__last)) -> ((element(flag~, [i_]) = red) or (element(flag~, [i_]) = white))) . H8: not (i = j) . H9: j >= pointerrange__first . H10: j <= pointerrange__last . H11: i >= pointerrange__first . H12: i <= pointerrange__last . H13: i >= indexrange__first . H14: i <= indexrange__last . H15: element(flag, [i]) = red . H16: i + 1 >= justbiggerrange__first . H17: i + 1 <= justbiggerrange__last . -> C1: indexrange__first <= i + 1 . C2: j <= indexrange__last + 1 . C3: i + 1 <= j . C4: for_all (q_: integer, ((q_ >= indexrange__first) and ( q_ <= i )) -> (element(flag, [q_]) = red)) . C5: for_all (r_: integer, ((r_ >= j) and (r_ <= indexrange__last)) -> (element(flag, [r_]) = white)) . C6: for_all (i___1: integer, ((i___1 >= indexrange__first) and ( i___1]) >= colour__first) and (element(flag, [i___1]) <= colour__last))) . C7: for_all (i_: integer, ((i_ >= indexrange__first) and ( i_ <= indexrange__last)) -> ((element(flag~, [i_]) = red) or (element(flag~, [i_]) = white))) . Nov-18 CIAO DFKI Bremen
35
Polish Flag [ loop-then ]
j l .… …. .… Given: red red white f i j l .… …. .… Goal: red white Nov-18 CIAO DFKI Bremen
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.