280 likes | 381 Views
Reusable PVS Proof Strategies for Proving Abstraction Properties of I/O Automata. Myla Archer Code 5546 Naval Research Laboratory archer@itd.nrl.navy.mil. Sayan Mitra MIT Computer Sc. and AI Lab mitras@csail.mit.edu. Outline. Background I/O Automata TAME Design Class ‘ automaton’
E N D
Reusable PVS Proof Strategies for Proving Abstraction Properties of I/O Automata Myla Archer Code 5546 Naval Research Laboratory archer@itd.nrl.navy.mil Sayan Mitra MIT Computer Sc. and AI Lab mitras@csail.mit.edu
Outline • Background • I/O Automata • TAME • Design • Class ‘automaton’ • Property theories • Template for abstraction properties • Strategy for weak refinement • Experimental results • Conclusions
Background: I/O Automata • Basic I/O automaton model (IOA) • Discrete events (no timing or probability) • Parallel composition • Levels of abstractions • Automaton [MMT ’91] • X: set of state variables • now єX: a special ‘real time’ variable • Q: states, a set of valuations of X • Q: start states • A = I O H: input, output, invisible actions • nu єA: a special time passage action • D Q A Q: discrete transitions visible actions
I/O Automaton Executions and Invariants • Execution • Alternating sequence s0a1s1a2s2…, where: • Each (si, ai ,si+1) is a discrete step • Beginning in a start state, s0є • Trace (external behavior): execution restricted to external actions • Invariant properties (true in all reachable states): • basecase: • inductionstep:
TAME • TAME [Archer ’02] provides a set of strategies that exploit the above proof structure to partially automate invariant proofs. • Templates • Specifying IOA as PVS theories • Invariant properties as theorems • Generic strategies for proving invariants • Reusable : independent of particular IOA • Relies on IOA template, and structure of invariant theorems.
I/O Automata Traces and Implementation relations • Some properties cannot be formalized as invariants • A implementsB if they have the same set of external actions and traces(A) traces(B). • Abstraction properties • Homomorphism • Refinement, weak refinement • Forward and backward simulation
Case Study : TIP • Tree Identification Phase of IEEE 1394: leader election algorithm. • Algorithm starts after a reset which clears all topology information except local information • Leaf nodes send parent request (PR) message to neighbors • When a node receives PR from all but one of its neighbors then it sends a PR to the remaining neighbor. PRs are ACKed • Tree grows from leaf to root • Node receiving an ACK terminates as a non-root. • Node receiving PR from all its neighbors is root --- leader. • Root contentions are broken by back-off and random retransmit. • Correctness • # leaders always <= 1 • Eventually, # leaders = 1
actions: DATATYPEnu(t) add_child(edge) children_known(vertices) ack(edges) resolve_contention(edges)root(vertices) noop:noop? visible(a):bool = root?(a) or nu?(a)states: TYPE = [# init: [Vertices -> Bool], contention: [Vertices -> Bool], root:[Vertices->Bool], child: [Edges -> Bool], mq:[Edges -> BoolStar] #]enabled_general (a, s):Bool = true enabled_specific (a, s):Bool = nu(t):t > zero, add_child(e): init(target(e),s) & not(mq(e,s)=null), … root(v): not(init(v,s)) & not(contention(v,s)) & not(root(v,s)) & (forall (e:tov(v)):child(e,s)), noop:true enabled (a, s):Bool= enabled_general(a,s) & enabled_specific(a,s) trans (a, s):states = nu(t): s WITH [now := now(s) + t],add_child(e):… … root(v): s WITH [basic:= basic(s) with [root:= root(basic(s)) with [(v):= true]]],noop: s start (s):Bool = s = (# basic := basic(s) with ….
SPEC actions: DATATYPEroot(vertices) nu(t) noop states: TYPE = [# done:bool #] enabled_general (a, s):bool = true; enabled_specific (a, s):bool = nu(t): t > zero,root(v): not(done(s)),noop: true enabled (a, s):bool = enabled_general(a,s) & enabled_specific(a,s) trans (a, s):states =nu(t): s WITH [now := now(s) + t],root(v): s WITH [basic:= basic(s) with [done := true]],noop : s start: [states -> bool] = LAMBDA(s):s = (# basic := basic(s) with [done:= false], now := zero, first := (LAMBDA (a:spec_actions): zero), last := (LAMBDA (a:spec_actions): infinity) #);
2. Design Issues • How to define abstraction properties (say, refinement) without referring to particular automata? • Cannot define a type "automaton" in PVS • How quantify over two automata? • Adapt the notion of an automaton object • A PVS theory with special structure • A automaton declaration written with TAME template is interpreted as an automaton object • The object can carry extra information: visible, reachable, etc. for property definitions • Introduce a templatefor importing automata definitions and defining a refinement relation between them • Essentially user has to rewrite the definition of refinement for every pair of automata • User has to be familiar with PVS naming conventions • Introduce a generic refinement theory which is imported in the context of the two automata to state the refinement relation • User has to write a new theory that matches the elements of the automata theories to elements of the generic theory
Design Issues (contd.) • Instead, parameterize generic refinement theory on automaton objects • Pass automata theories interpreted as automaton objects as parameters to a generic refinement theory • Automatic matching by name of theory elements to elements of automaton object • This matching is made possible by recent PVS enhancements, making it easier to pass theory parameters. • How to distinguish between analogous objects (e.g. A.states vs B.states) from two automata when communicating with the prover? • Formal theory-parameter names can be used as prefixes on objects from the actual theories
Automaton Class Template for Abstraction properties Theorem: MA implements MB import Abstraction Property 3. Pieces in PVS Specification of an Abstraction property A Interpretation i MA iii B Interpretation MB ii
Rest of the Talk • Background • Previous barriers • Pieces in PVS specification • Class ‘automaton’ • Property theories • Template for abstraction properties • Strategy for weak refinement • Experimental results • Conclusions
i. Class automaton automaton : THEORY BEGIN actions : TYPE+ states : TYPE+ visible (a: actions) : bool start (s: states) : bool enabled (a: actions, s: states) : bool trans (a: actions, s: states): states reachable (s: states): bool converts (s1 , s2 : states) : bool END automaton
sB1 sB2 sB3 ii. Property Theories : Forward Simulation fwd_sim_base: FORALL sA, If A.start(sA) then EXISTS sB, B.start(sB) and r(sA,sB); fwd_sim_step FORALL sA, sA’, sB, aA, r(sA,sB) & A.enabled(aA,sA) & sA’ = A.trans(aA,sA) implies If A.visible(aA) then EXISTS sB1, sB2, sB3, converts(sB,sB1) & converts(sB2,sB2) & r(sA’, sB3) & B.enabled(actmap(aA), sB1) & B.trans(actmap(aA),sB1) = sB2) else EXISTS sB3, converts(sB, sB3) & r(sA’, sB3) sB sB3 sB actmap r r r r aA aA sA sA’ sA sA’ Visible Invisible
ii. Property Theories : Weak Refinement weak_refinement_base FORALL sA:A.states, if A.start(sA) thenB.start(r(sA)) weak_refinement_step FORALL sA, aA, A.reachable(sA) & A.enabled(aA,sA) implies if A.visible(aA) then B.enabled(actmap(aA),r(sA)) and r(A.trans(aA,sA)) = B.trans(actmap(aA),r(sA)) else r(sA) = r(A.trans(aA,sA)) or r(A.trans(aA,sA)) = B.trans(actmap(aA),r(sA)) weak_refinement THEOREM weak_refinement_base and weak_refinement_step
iii. Template for Abstraction Properties Initial theory imports for TIP and SPEC MA : THEORY = automaton :-> tip_decls MB : THEORY = automaton :-> spec_decls amap(aA: MA.actions): MB.actions = CASES aA OF nu(t): nu(t), add_child(e):noop, children_known(c): noop, ack(a): noop, resolve_contention(r): noop, root(v): root(v), noop:noop ENDCASES ref(sC: MC.states): MA.states = (# basic := (# done := EXISTS (v:Vertices): root(v,s_C) #), now := now(s_C) #) IMPORTING weak_refinement[MA,MC, amap, ref] weak_refinement_theorem: THEOREM refinement
DO_TRANS DO_TRANS APPLY_SPECIFIC_PRECOND APPLY_GENERAL_PRECOND PROVE_REFINEMENT PROVE_REFINEMENT SETUP_REF_BASE SETUP_REF_INDUCT_CASES START_REF_INDUCTION_BRANCH START_REF_INDUCTION_BRANCH START_ENABLEMENT_PROOF
DO_TRANS APPLY_SPECIFIC_PRECOND APPLY_GENERAL_PRECOND PROVE_REFINEMENT Strategy PROVE_REFINEMENT SETUP_REF_BASE SETUP_REF_INDUCT_CASES START_REF_INDUCTION_BRANCH START_REF_INDUCTION_BRANCH DO_TRANS START_ENABLEMENT_PROOF weak_refinement : weak_refinement_base & weak_refinement_step weak_refinement_base : FORALL sc:A.states, if A.start(sc) thenB.start(r(sc)) weak_refinement_step : FORALL sc, ac, A.reachable(sC) & A.enabled(aC,sC) implies if A.visible(aC) then B.enabled(actmap(aC),r(sC)) and r(A.trans(aC,sC)) = B.trans(actmap(aC),r(sC)) else r(sC) = r(A.trans(aC,sC)) or r(A.trans(aC,sC)) = B.trans(actmap(aC),r(sC))
PROVE_REFINEMENT SETUP_REF_BASE SETUP_REF_INDUCT_CASES START_REF_INDUCTION_BRANCH START_REF_INDUCTION_BRANCH DO_TRANS START_ENABLEMENT_PROOF DO_TRANS APPLY_SPECIFIC_PRECOND APPLY_GENERAL_PRECOND SETUP_REF_BASE (defstepsetup_ref_base (concsimpstrat abssimpstrat) (then (expand "refinement_base") (skolem 1 "sC_1") (flatten) (expand "start") (expand "ref") concsimpstratabssimpstrat)"" "")
PROVE_REFINEMENT SETUP_REF_BASE SETUP_REF_INDUCT_CASES START_REF_INDUCTION_BRANCH START_REF_INDUCTION_BRANCH DO_TRANS START_ENABLEMENT_PROOF DO_TRANS APPLY_SPECIFIC_PRECOND APPLY_GENERAL_PRECOND START_ENABLEMENT_PROOF (defstepstart_enablement_proof (comment-string) (let ((gencomcmd (setq *gencomcmd* `(comment ,(formatnil "~a~a" comment-string "general enablement")))) (speccomcmd (setq *speccomcmd* `(comment ,(formatnil "~a~a" comment-string "specific enablement"))))) (then (expand "enabled" "enabled C.action" :assert? NONE) (with-labels (flatten) (("C.general-precondition" "C.specific-precondition"))) (expand "enabled" "enabled A.action" :assert? NONE) (branch (with-labels (split) (("A.general-precondition" "A.specific-precondition"))) ((then (apply_general_precond) gencomcmd (time_simp) (postpone)) (then (apply_specific_precond) speccomcmd (postpone)))))) "" "")
TIP Walkthrough: Proof Stages weak_refinement : |------- {1} refinement Rule? (PROVE_REFINEMENT) {-1,(base-case)} s_C!1 = (# basic := basic(s_C!1) WITH [init := LAMBDA (v: Vertices): TRUE, contention := LAMBDA (v: Vertices): FALSE, root := LAMBDA (v: Vertices): FALSE, child := LAMBDA (e: Edges): FALSE, mq := LAMBDA (e: Edges): null], now := zero, first := (LAMBDA (a: actions): zero), last := (LAMBDA (a: actions): infinity) #) |------- {1,(base-case)} NOT (EXISTS (v: Vertices): root(v, s_C!1)) AND now(s_C!1) = zero Rule? (SETUP_REF_BASE)
TIP Walkthrough: Proof Stages ;;; Case nu(timeof_C_action) enablement [-1,(reachable C.prestate)] reachable(s_C_theorem) [-2,(enabled C.action)] enabled(nu(timeof_C_action), s_C_theorem) |------- [1,(enabled A.action)] tip_spec_decls.enabled (nu(timeof_C_action), (# basic := (# done := EXISTS (v: Vertices): root(v, s_C_theorem) #), now := now(s_C_theorem), first := (LAMBDA (a: MA.actions): zero), last := (LAMBDA (a: MA.actions): infinity) #))
TIP Walkthrough: Proof Stages ;;; Transitions correspond for nu {-1,(enabled A.action)} tip_spec_decls.enabled(nu(timeof_C_action), (# basic := (# done := EXISTS (v: Vertices): root(v, s_C_theorem) #), now := now(s_C_theorem), first := (LAMBDA (a: MA.actions): zero), last := (LAMBDA (a: MA.actions): infinity) #)) [-2,(reachable C.prestate)] reachable(s_C_theorem) [-3,(enabled C.action)] enabled(nu(timeof_C_action), s_C_theorem) |------- {1,(congruence)} ((# basic := (# done := EXISTS (v: Vertices): root(v, trans(nu(timeof_C_action), s_C_theorem)) #), now := now(trans(nu(timeof_C_action), s_C_theorem)), first := (LAMBDA (a: MA.actions): zero), last := (LAMBDA (a: MA.actions): infinity) #) = tip_spec_decls.trans(nu(timeof_C_action), (# basic := (# done := EXISTS (v: Vertices): root(v, s_C_theorem) #), now := now(s_C_theorem), first := (LAMBDA (a: MA.actions): zero), last := (LAMBDA (a: MA.actions): infinity) #)))
Tip Proof ("" (prove_refinement) (("1" ;; Case root(rootV_C_action) specific enablement case (skolem_in "A.specific-precondition" "v_1") (apply_inv_lemma "15" "s_C_theorem") ;; Applying the lemma ;; (EXISTS (v: Vertices): FORALL (e: tov(v)): child(e, s_C_theorem)) => ;; ((EXISTS (v: Vertices): FORALL (e: tov(v)): child(e, s_C_theorem)) & ;; (FORALL (v, w: Vertices): ;; (((FORALL (e: tov(v)): child(e, s_C_theorem)) & ;; (FORALL (e: tov(w)): child(e, s_C_theorem))) => v = w))) (inst_in "lemma_15" "rootV_C_action") (inst_in "lemma_15" "v_1" "rootV_C_action") (inst_in "lemma_15" "v_1" "rootV_C_action") (skolem_in "lemma_15" "e_1") (apply_inv_lemma "13" "s_C_theorem" "e_1")) ;; Applying the lemma ;; FORALL (e: Edges): root(target(e), s_C_theorem) +> child(e, s_C_theorem) (try_simp) (“2" ;; Case root(rootV_C_action) congruence (inst "congruence" "rootV_C_action") (try_simp))))
5. Other Case Studies • Specification and implementation of failure prone memory component[ Romijn 1996] • REL_MEM: concrete automaton • MEM: Abstract automaton, same as MEM without fail action • The refinement relation refis a bijection • The action map amap is an injection • Trace inclusion proved by weak refinement • Proved completely automatically using (prove_refinement)
Forward Simulation • Concrete automaton: composition of P C T [Kaynar, et. al. 2004 ] • Send process P sends a message every u1 time until fail action occurs • Channel C delivers message with a max delay b • Timeout process Ttimes out if it does not receive a message for more than u2time, and suspects P to be failed • Property to check: • If u2 > u1 + b then suspects failed • Abstract automaton: • A fail action is followed by timeout in u2 + b time • Trace inclusion proved by forward simulation in PVS • Developing strategy PROVE_FWD_SIM • Initial proof steps are similar to PROVE_REFINEMENT • Needs addition TAME sub strategies
Conclusions • Specification of abstraction properties in PVS/ TAME • Automaton object / theory • Library of abstraction property theories • Template for stating abstraction properties as theorems • Reusable strategy for proving weak refinement in TAME • User friendly interactive proving • Template for developing strategies for proving other abstraction relations • Add other abstraction relations to library • Develop PROVE_FWD_SIM and others • Integrate with TIOA tools