3 Author: Lawrence C Paulson |
3 Author: Lawrence C Paulson |
4 Copyright 1999 University of Cambridge |
4 Copyright 1999 University of Cambridge |
5 |
5 |
6 Installing the oracle for SVC (Stanford Validity Checker) |
6 Installing the oracle for SVC (Stanford Validity Checker) |
7 |
7 |
8 The following code merely CALLS the oracle; |
8 The following code merely CALLS the oracle; |
9 the soundness-critical functions are at HOL/Tools/svc_funcs.ML |
9 the soundness-critical functions are at HOL/Tools/svc_funcs.ML |
10 |
10 |
11 Based upon the work of Søren T. Heilmann |
11 Based upon the work of Søren T. Heilmann |
12 *) |
12 *) |
13 |
13 |
24 and body = Term.strip_all_body t |
24 and body = Term.strip_all_body t |
25 val Us = map #2 params |
25 val Us = map #2 params |
26 val nPar = length params |
26 val nPar = length params |
27 val vname = ref "V_a" |
27 val vname = ref "V_a" |
28 val pairs = ref ([] : (term*term) list) |
28 val pairs = ref ([] : (term*term) list) |
29 fun insert t = |
29 fun insert t = |
30 let val T = fastype_of t |
30 let val T = fastype_of t |
31 val v = Unify.combound (Var ((!vname,0), Us--->T), |
31 val v = Unify.combound (Var ((!vname,0), Us--->T), |
32 0, nPar) |
32 0, nPar) |
33 in vname := Symbol.bump_string (!vname); |
33 in vname := Symbol.bump_string (!vname); |
34 pairs := (t, v) :: !pairs; |
34 pairs := (t, v) :: !pairs; |
35 v |
35 v |
36 end; |
36 end; |
37 fun replace t = |
37 fun replace t = |
38 case t of |
38 case t of |
39 Free _ => t (*but not existing Vars, lest the names clash*) |
39 Free _ => t (*but not existing Vars, lest the names clash*) |
40 | Bound _ => t |
40 | Bound _ => t |
41 | _ => (case gen_assoc Pattern.aeconv (!pairs, t) of |
41 | _ => (case gen_assoc Pattern.aeconv (!pairs, t) of |
42 SOME v => v |
42 SOME v => v |
43 | NONE => insert t) |
43 | NONE => insert t) |
44 (*abstraction of a numeric literal*) |
44 (*abstraction of a numeric literal*) |
45 fun lit (t as Const("0", _)) = t |
45 fun lit (t as Const("0", _)) = t |
46 | lit (t as Const("1", _)) = t |
46 | lit (t as Const("1", _)) = t |
47 | lit (t as Const("Numeral.number_of", _) $ w) = t |
47 | lit (t as Const("Numeral.number_of", _) $ w) = t |
48 | lit t = replace t |
48 | lit t = replace t |
64 | nat ((c as Const("op *", _)) $ x $ y) = c $ (nat x) $ (nat y) |
64 | nat ((c as Const("op *", _)) $ x $ y) = c $ (nat x) $ (nat y) |
65 | nat ((c as Const("Suc", _)) $ x) = c $ (nat x) |
65 | nat ((c as Const("Suc", _)) $ x) = c $ (nat x) |
66 | nat t = lit t |
66 | nat t = lit t |
67 (*abstraction of a relation: =, <, <=*) |
67 (*abstraction of a relation: =, <, <=*) |
68 fun rel (T, c $ x $ y) = |
68 fun rel (T, c $ x $ y) = |
69 if T = HOLogic.realT then c $ (rat x) $ (rat y) |
69 if T = HOLogic.realT then c $ (rat x) $ (rat y) |
70 else if T = HOLogic.intT then c $ (int x) $ (int y) |
70 else if T = HOLogic.intT then c $ (int x) $ (int y) |
71 else if T = HOLogic.natT then c $ (nat x) $ (nat y) |
71 else if T = HOLogic.natT then c $ (nat x) $ (nat y) |
72 else if T = HOLogic.boolT then c $ (fm x) $ (fm y) |
72 else if T = HOLogic.boolT then c $ (fm x) $ (fm y) |
73 else replace (c $ x $ y) (*non-numeric comparison*) |
73 else replace (c $ x $ y) (*non-numeric comparison*) |
74 (*abstraction of a formula*) |
74 (*abstraction of a formula*) |
75 and fm ((c as Const("op &", _)) $ p $ q) = c $ (fm p) $ (fm q) |
75 and fm ((c as Const("op &", _)) $ p $ q) = c $ (fm p) $ (fm q) |
76 | fm ((c as Const("op |", _)) $ p $ q) = c $ (fm p) $ (fm q) |
76 | fm ((c as Const("op |", _)) $ p $ q) = c $ (fm p) $ (fm q) |
77 | fm ((c as Const("op -->", _)) $ p $ q) = c $ (fm p) $ (fm q) |
77 | fm ((c as Const("op -->", _)) $ p $ q) = c $ (fm p) $ (fm q) |
78 | fm ((c as Const("Not", _)) $ p) = c $ (fm p) |
78 | fm ((c as Const("Not", _)) $ p) = c $ (fm p) |
90 |
90 |
91 |
91 |
92 (*Present the entire subgoal to the oracle, assumptions and all, but possibly |
92 (*Present the entire subgoal to the oracle, assumptions and all, but possibly |
93 abstracted. Use via compose_tac, which performs no lifting but will |
93 abstracted. Use via compose_tac, which performs no lifting but will |
94 instantiate variables.*) |
94 instantiate variables.*) |
95 local val svc_thy = the_context () in |
|
96 |
95 |
97 fun svc_tac i st = |
96 fun svc_tac i st = |
98 let val prem = BasisLibrary.List.nth (prems_of st, i-1) |
97 let |
99 val (absPrem, _) = svc_abstract prem |
98 val (abs_goal, _) = svc_abstract (Logic.get_goal (Thm.prop_of st) i) |
100 val th = invoke_oracle svc_thy "svc_oracle" |
99 val th = svc_oracle (Thm.theory_of_thm st) abs_goal |
101 (#sign (rep_thm st), Svc.OracleExn absPrem) |
100 in compose_tac (false, th, 0) i end |
102 in |
101 handle TERM _ => no_tac; |
103 compose_tac (false, th, 0) i st |
|
104 end |
|
105 handle Svc.OracleExn _ => Seq.empty |
|
106 | Subscript => Seq.empty; |
|
107 |
|
108 end; |
|
109 |
102 |
110 |
103 |
111 (*check if user has SVC installed*) |
104 (*check if user has SVC installed*) |
112 fun svc_enabled () = getenv "SVC_HOME" <> ""; |
105 fun svc_enabled () = getenv "SVC_HOME" <> ""; |
113 fun if_svc_enabled f x = if svc_enabled () then f x else (); |
106 fun if_svc_enabled f x = if svc_enabled () then f x else (); |