Presentation is loading. Please wait.

Presentation is loading. Please wait.

A Verification Condition Visualizer

Similar presentations


Presentation on theme: "A Verification Condition Visualizer"— Presentation transcript:

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


Download ppt "A Verification Condition Visualizer"

Similar presentations


Ads by Google