Integrated Verification Approaches Using Agda
This paper discusses integrated verification techniques utilizing Agda for goal decomposition into subgoals. The proposed method modifies the type checker to connect with various verification tools, ensuring that the decomposition is sound through type-checking. The approach includes examples like equation solvers and showcases how to automate the checking of subgoals. Challenges such as guarantee issues and complex types are addressed while presenting templates for program structure. The work aims to enhance modular verification and streamline the use of external tools within Agda.
Integrated Verification Approaches Using Agda
E N D
Presentation Transcript
Integrated? Verification using Agda Compiler 2009-09-14 AIM10 Makoto Takeyama AIST/CVS
Basic Idea • Integrated Verification • Use Agda to decompose a goal to subgoals. • Use automatic tools to check subgoals. • Usual approach • Modify the type checker to connect to tools. • Compiled(?) approach • Write an Agda program such that • Type checking it ensures decomposition is correct; • Running it checks subgoals.
Compiled approach • To show goal Gfrom subgoal P to be checked by a tool :(P … a “problem” for the tool) module Main wheremyproof : P → G myproof = …(usual Agda proof)… main : IO Unit main = check P >>= λ result → if result == OK then putStrLn "OK" else putStrLn "NG" run the tool on P
Issues • You can’t write check : Set → IO Result • No guarantee for the main to be checking what is assumed in myproof. • Many P’s / myproof’s / tools? module Main wheremyproof : P → G myproof = ...(usual Agda proof)... main : IO Unit main = check P >>= λ result → if result == OK then putStrLn "OK" else putStrLn "NG" run the tool on P
1. Problem description • To program check P in Agda, P can’t be a set. • Prepare Prob : Set -- data type of problem descriptions ⟦_⟧ : Prob → Set -- meaning as a set • and write check : Prob → IO Result module Main wheremyproof : ⟦ P⟧ → G myproof = ... main : IO Unit main = check P >>= λ result → if result == OK then putStrLn "OK" else putStrLn "NG"
1. Problem description • E.g. equation solver (using RingSolver setup) data Prob : Set whereeqn : (n : ℕ)→N-ary n (Poly n)(Poly n × Poly n)→ Prob(n-ary function returning a pair of n-variable polynomials) ⟦_⟧ : Prob → Set is programmed so that, e.g, P = eqn 3 λ x y z → ( x :* (y :+ z) ,y :* x :+ z :* x ) decodes to ⟦ P ⟧ = ∀ (x y z : ℕ) → x * (y + z) ≡ y * x + z * x
1. Problem description • cont. equation solver check P =readProcess “yices” [ ] (print P) >>= λoutput → if output == “unsat” then return resultOK else return resultNG where, for P = eqn 3 λx y z → ( x :* (y :+ z) , y :* x :+ z :* x ), print P is “(define x0::nat) (define x1::nat) (define x2::nat) (assert (/= (* x0 (+ y z)) (+ (* x1 x0) (* x2 x0)))”
2. A template for main module Main wheremyproof : ⟦ P⟧ → G myproof = ... main : IO Unit main = check P’ >>= ... • Type checking won’t tell whether what’s checked is what’s assumed. • Make it a rule to use a template for mainthat forces the check.template : ∀ P {G} (prf : ⟦P⟧→G) → IO Unittemplate P prf = check P >>= … dummy arg just for type checking • If this type checks, what’s checked is what’s assumed. ...main = template P myproof
3. Combining tools : IV.agda • For each tool i, prepare a record Diof Prob : Set ⟦_⟧ : Prob → Set Check : Prob → IO Result • module IV.IV (D0::D1::D3…) provides • Combined record D whereProb consists of and/or combinations of Pi ’ s,Check does short-circuited checking. • A template for main that takes a list of proofswhose assumptions are to be checked.
Instances • IV.Spin.agda (with Yamagata) • (‘Promela AST’ ⊢ ‘LTL formula’) : Prob • ⟦ M ⊢ φ⟧ = M ⊨ φ , but _⊨_ is just a postulate. • (Agda version of Text.PrettyPrint.hs) • IV.NatSolve.agda • Checks and/or/not- combination of equality/inequality among polynomials on Nat. • SMT solver “yices” (using only a miniscule part)
Misc. • Not fiddling with Agda source code is good. • “interactive” use is possible, but too slow. • P : Prob could be a more complex tactics. • Alt. approaches? A: Check : (P : Prob) → IO(Result ⟦ P ⟧) main : IO(Result G) main = … (any type correct plumbing) … B: A state monad accumulating assumptions used? • Combining with certificate-checking approach?(untrusted certificate finder & proven certificate checker run at run time) • Generating P from ⟦ P ⟧ in Agda? phantom type
Prob : SetCert : Set_`certifies`_ : Cert → Prob → Boolsound : ∀ P C → C `certifies` P ≡ true → ⟦P⟧ findCert : Prob → IO Cert -- no need to trust this myprf : IO ⟦P⟧ myprf = findCert P >>= checkCert where checkCert : Cert → IO ⟦P⟧ checkCert C with inspect (C `certifies` P) … | true with-≡ eq = return (sound P C eq) … | _ = fail (“Failed :” ++ show P)