120 likes | 244 Views
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
E N D
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)