11522

1 
(* Title: Pure/Proof/proof_syntax.ML


2 
ID: $Id$


3 
Author: Stefan Berghofer


4 
Copyright 2000 TU Muenchen


5 


6 
Function for parsing and printing proof terms.


7 
*)


8 


9 
signature PROOF_SYNTAX =


10 
sig


11 
val proofT : typ


12 
val add_proof_syntax : Sign.sg > Sign.sg


13 
val disambiguate_names : theory > Proofterm.proof >


14 
Proofterm.proof * Proofterm.proof Symtab.table


15 
val proof_of_term : theory > Proofterm.proof Symtab.table >


16 
bool > term > Proofterm.proof


17 
val term_of_proof : Proofterm.proof > term


18 
val cterm_of_proof : theory > Proofterm.proof > cterm * (cterm > Proofterm.proof)


19 
val read_term : theory > typ > string > term


20 
val read_proof : theory > bool > string > Proofterm.proof


21 
val pretty_proof : Sign.sg > Proofterm.proof > Pretty.T


22 
val pretty_proof_of : bool > thm > Pretty.T


23 
val print_proof_of : bool > thm > unit


24 
end;


25 


26 
structure ProofSyntax : PROOF_SYNTAX =


27 
struct


28 


29 
open Proofterm;


30 


31 
(**** add special syntax for embedding proof terms ****)


32 


33 
val proofT = Type ("proof", []);


34 
val lamT = Type ("lam_syn", []);


35 
val idtT = Type ("idt", []);


36 
val aT = TFree ("'a", ["logic"]);


37 


38 
(** constants for theorems and axioms **)


39 


40 
fun add_prefix a b = NameSpace.pack (a :: NameSpace.unpack b);


41 


42 
fun add_proof_atom_consts names sg = Sign.add_consts_i


43 
(map (fn name => (name, proofT, NoSyn)) names) (Sign.add_path "//" sg);


44 


45 
(** constants for application and abstraction **)


46 


47 
fun add_proof_syntax sg =


48 
sg


49 
> Sign.copy


50 
> Sign.add_path "/"


51 
> Sign.add_defsort_i ["logic"]


52 
> Sign.add_types [("proof", 0, NoSyn)]


53 
> Sign.add_arities [("proof", [], "logic")]


54 
> Sign.add_consts_i


55 
[("Appt", [proofT, aT] > proofT, Mixfix ("(1_ %%/ _)", [4, 5], 4)),


56 
("AppP", [proofT, proofT] > proofT, Mixfix ("(1_ %/ _)", [4, 5], 4)),


57 
("Abst", (aT > proofT) > proofT, NoSyn),


58 
("AbsP", [propT, proofT > proofT] > proofT, NoSyn)]


59 
> Sign.add_nonterminals ["lam_syn"]


60 
> Sign.add_syntax_i


61 
[("_Lam", [lamT, proofT] > proofT, Mixfix ("(3Lam _./ _)", [0,0], 1)),


62 
("_Lam0", [lamT, lamT] > lamT, Mixfix ("_,/ _", [1, 0], 0)),


63 
("_Lam1", [idtT, propT] > lamT, Mixfix ("_ : _", [0, 0], 1)),


64 
("_Lam2", idtT > lamT, Mixfix ("_", [0], 1))]


65 
> Sign.add_modesyntax_i (("xsymbols", true),


66 
[("_Lam", [lamT, proofT] > proofT, Mixfix ("(3\\<Lambda>_./ _)", [0,0], 1)),


67 
("Appt", [proofT, aT] > proofT, Mixfix ("(1_ \\<cdot>/ _)", [4, 5], 4)),


68 
("AppP", [proofT, proofT] > proofT, Mixfix ("(1_ \\<bullet>/ _)", [4, 5], 4))])


69 
> Sign.add_trrules_i (map Syntax.ParsePrintRule


70 
[(Syntax.mk_appl (Constant "_Lam")


71 
[Syntax.mk_appl (Constant "_Lam1") [Variable "x", Variable "A"], Variable "B"],


72 
Syntax.mk_appl (Constant "AbsP") [Variable "A",


73 
(Syntax.mk_appl (Constant "_abs") [Variable "x", Variable "B"])]),


74 
(Syntax.mk_appl (Constant "_Lam")


75 
[Syntax.mk_appl (Constant "_Lam2") [Variable "x"], Variable "A"],


76 
Syntax.mk_appl (Constant "Abst")


77 
[(Syntax.mk_appl (Constant "_abs") [Variable "x", Variable "A"])]),


78 
(Syntax.mk_appl (Constant "_Lam")


79 
[Syntax.mk_appl (Constant "_Lam0") [Variable "l", Variable "m"], Variable "A"],


80 
Syntax.mk_appl (Constant "_Lam")


81 
[Variable "l", Syntax.mk_appl (Constant "_Lam") [Variable "m", Variable "A"]])]);


82 


83 


84 
(**** create unambiguous theorem names ****)


85 


86 
fun disambiguate_names thy prf =


87 
let


88 
val thms = thms_of_proof Symtab.empty prf;


89 
val thms' = map (apsnd (#prop o rep_thm)) (flat


90 
(map PureThy.thms_of (thy :: Theory.ancestors_of thy)));


91 


92 
val tab = Symtab.foldl (fn (tab, (key, ps)) =>


93 
let val prop = if_none (assoc (thms', key)) (Bound 0)


94 
in fst (foldr (fn ((prop', prf), x as (tab, i)) =>


95 
if prop <> prop' then


96 
(Symtab.update ((key ^ "_" ^ string_of_int i, prf), tab), i+1)


97 
else x) (ps, (tab, 1)))


98 
end) (Symtab.empty, thms);


99 


100 
fun rename (Abst (s, T, prf)) = Abst (s, T, rename prf)


101 
 rename (AbsP (s, t, prf)) = AbsP (s, t, rename prf)


102 
 rename (prf1 % prf2) = rename prf1 % rename prf2


103 
 rename (prf %% t) = rename prf %% t


104 
 rename (prf' as PThm ((s, tags), prf, prop, Ts)) =


105 
let


106 
val prop' = if_none (assoc (thms', s)) (Bound 0);


107 
val ps = map fst (the (Symtab.lookup (thms, s))) \ prop'


108 
in if prop = prop' then prf' else


109 
PThm ((s ^ "_" ^ string_of_int (length ps  find_index_eq prop ps), tags),


110 
prf, prop, Ts)


111 
end


112 
 rename prf = prf


113 


114 
in (rename prf, tab) end;


115 


116 


117 
(**** translation between proof terms and pure terms ****)


118 


119 
fun change_type T (PThm (name, prf, prop, _)) = PThm (name, prf, prop, T)


120 
 change_type T (PAxm (name, prop, _)) = PAxm (name, prop, T)


121 
 change_type _ _ = error "Not a proper theorem";


122 


123 
fun proof_of_term thy tab ty =


124 
let


125 
val thys = thy :: Theory.ancestors_of thy;


126 
val thms = flat (map thms_of thys);


127 
val axms = flat (map (Symtab.dest o #axioms o rep_theory) thys);


128 


129 
fun prf_of [] (Bound i) = PBound i


130 
 prf_of Ts (Const (s, Type ("proof", _))) =


131 
change_type (if ty then Some Ts else None)


132 
(case NameSpace.unpack s of


133 
"Axm" :: xs =>


134 
let


135 
val name = NameSpace.pack xs;


136 
val prop = (case assoc (axms, name) of


137 
Some prop => prop


138 
 None => error ("Unknown axiom " ^ quote name))


139 
in PAxm (name, prop, None) end


140 
 "Thm" :: xs =>


141 
let val name = NameSpace.pack xs;


142 
in (case assoc (thms, name) of


143 
Some thm => fst (strip_combt (#2 (#der (rep_thm thm))))


144 
 None => (case Symtab.lookup (tab, name) of


145 
Some prf => prf


146 
 None => error ("Unknown theorem " ^ quote name)))


147 
end


148 
 _ => error ("Illegal proof constant name: " ^ quote s))


149 
 prf_of Ts (v as Var ((_, Type ("proof", _)))) = Hyp v


150 
 prf_of [] (Const ("Abst", _) $ Abs (s, T, prf)) =


151 
Abst (s, if ty then Some T else None,


152 
incr_pboundvars (~1) 0 (prf_of [] prf))


153 
 prf_of [] (Const ("AbsP", _) $ t $ Abs (s, _, prf)) =


154 
AbsP (s, case t of Const ("dummy_pattern", _) => None  _ => Some t,


155 
incr_pboundvars 0 (~1) (prf_of [] prf))


156 
 prf_of [] (Const ("AppP", _) $ prf1 $ prf2) =


157 
prf_of [] prf1 % prf_of [] prf2


158 
 prf_of Ts (Const ("Appt", _) $ prf $ Const ("TYPE", Type (_, [T]))) =


159 
prf_of (T::Ts) prf


160 
 prf_of [] (Const ("Appt", _) $ prf $ t) = prf_of [] prf %%


161 
(case t of Const ("dummy_pattern", _) => None  _ => Some t)


162 
 prf_of _ t = error ("Not a proof term:\n" ^


163 
Sign.string_of_term (sign_of thy) t)


164 


165 
in prf_of [] end;


166 


167 


168 
val AbsPt = Const ("AbsP", [propT, proofT > proofT] > proofT);


169 
val AppPt = Const ("AppP", [proofT, proofT] > proofT);


170 
val Hypt = Free ("Hyp", propT > proofT);


171 
val Oraclet = Free ("Oracle", propT > proofT);


172 
val MinProoft = Free ("?", proofT);


173 


174 
val mk_tyapp = foldl (fn (prf, T) => Const ("Appt",


175 
[proofT, itselfT T] > proofT) $ prf $ Logic.mk_type T);


176 


177 
fun term_of _ (PThm ((name, _), _, _, None)) =


178 
Const (add_prefix "Thm" name, proofT)


179 
 term_of _ (PThm ((name, _), _, _, Some Ts)) =


180 
mk_tyapp (Const (add_prefix "Thm" name, proofT), Ts)


181 
 term_of _ (PAxm (name, _, None)) = Const (add_prefix "Axm" name, proofT)


182 
 term_of _ (PAxm (name, _, Some Ts)) =


183 
mk_tyapp (Const (add_prefix "Axm" name, proofT), Ts)


184 
 term_of _ (PBound i) = Bound i


185 
 term_of Ts (Abst (s, opT, prf)) =


186 
let val T = if_none opT dummyT


187 
in Const ("Abst", (T > proofT) > proofT) $


188 
Abs (s, T, term_of (T::Ts) (incr_pboundvars 1 0 prf))


189 
end


190 
 term_of Ts (AbsP (s, t, prf)) =


191 
AbsPt $ if_none t (Const ("dummy_pattern", propT)) $


192 
Abs (s, proofT, term_of (proofT::Ts) (incr_pboundvars 0 1 prf))


193 
 term_of Ts (prf1 % prf2) =


194 
AppPt $ term_of Ts prf1 $ term_of Ts prf2


195 
 term_of Ts (prf %% opt) =


196 
let val t = if_none opt (Const ("dummy_pattern", dummyT))


197 
in Const ("Appt",


198 
[proofT, fastype_of1 (Ts, t) handle TERM _ => dummyT] > proofT) $


199 
term_of Ts prf $ t


200 
end


201 
 term_of Ts (Hyp t) = Hypt $ t


202 
 term_of Ts (Oracle (_, t, _)) = Oraclet $ t


203 
 term_of Ts (MinProof _) = MinProoft;


204 


205 
val term_of_proof = term_of [];


206 


207 
fun cterm_of_proof thy prf =


208 
let


209 
val (prf', tab) = disambiguate_names thy prf;


210 
val thys = thy :: Theory.ancestors_of thy;


211 
val thm_names = filter_out (equal "") (map fst (flat (map thms_of thys))) @


212 
map fst (Symtab.dest tab);


213 
val axm_names = map fst (flat (map (Symtab.dest o #axioms o rep_theory) thys));


214 
val sg = sign_of thy >


215 
add_proof_syntax >


216 
add_proof_atom_consts


217 
(map (add_prefix "Thm") thm_names @ map (add_prefix "Axm") axm_names)


218 
in


219 
(cterm_of sg (term_of_proof prf'),


220 
proof_of_term thy tab true o Thm.term_of)


221 
end;


222 


223 
fun read_term thy =


224 
let


225 
val thys = thy :: Theory.ancestors_of thy;


226 
val thm_names = filter_out (equal "") (map fst (flat (map thms_of thys)));


227 
val axm_names = map fst (flat (map (Symtab.dest o #axioms o rep_theory) thys));


228 
val sg = sign_of thy >


229 
add_proof_syntax >


230 
add_proof_atom_consts


231 
(map (add_prefix "Thm") thm_names @ map (add_prefix "Axm") axm_names)


232 
in


233 
(fn T => fn s => Thm.term_of (read_cterm sg (s, T)))


234 
end;


235 


236 
fun read_proof thy =


237 
let val rd = read_term thy proofT


238 
in


239 
(fn ty => fn s => proof_of_term thy Symtab.empty ty (Logic.varify (rd s)))


240 
end;


241 


242 
fun pretty_proof sg prf =


243 
let


244 
val thm_names = map fst (Symtab.dest (thms_of_proof Symtab.empty prf)) \ "";


245 
val axm_names = map fst (Symtab.dest (axms_of_proof Symtab.empty prf));


246 
val sg' = sg >


247 
add_proof_syntax >


248 
add_proof_atom_consts


249 
(map (add_prefix "Thm") thm_names @ map (add_prefix "Axm") axm_names)


250 
in


251 
Sign.pretty_term sg' (term_of_proof prf)


252 
end;


253 


254 
fun pretty_proof_of full thm =


255 
let


256 
val {sign, der = (_, prf), prop, ...} = rep_thm thm;


257 
val prf' = (case strip_combt (fst (strip_combP prf)) of


258 
(PThm (_, prf', prop', _), _) => if prop=prop' then prf' else prf


259 
 _ => prf)


260 
in


261 
pretty_proof sign


262 
(if full then Reconstruct.reconstruct_prf sign prop prf' else prf')


263 
end;


264 


265 
val print_proof_of = Pretty.writeln oo pretty_proof_of;


266 


267 
end;
