-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShowTypes.thy
154 lines (137 loc) · 5.16 KB
/
ShowTypes.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
(*
* @TAG(NICTA_BSD)
*
* ShowTypes: show "hidden" type constraints in terms.
* This is a simple utility around Sledgehammer's type annotation code.
*
* Based on Sledgehammer_Isar_Annotate and related modules
* (by Blanchette and Smolka).
*
*
* Usage
* ----
* This theory provides the improper commands
* term_show_types <term>
* thm_show_types <thm> [<thm> ...]
* goal_show_types [N]
* as well as the ML function Show_Types.term_show_types.
*
* term_show_types and thm_show_types can be used as replacements
* for the term and thm commands.
*
*
* Known issues
* ----
* \<bullet> Type constraints for variables, etc. are not always printed.
* In that case, set show_types/show_sorts to get extra annotations.
*
* \<bullet> Doesn't print sort constraints. show_sorts will print them but
* the output may not be formatted properly.
*
* \<bullet> Doesn't compose with other term-display utils like Insulin.
*)
theory ShowTypes imports
Main
keywords "term_show_types" "thm_show_types" "goal_show_types" :: diag
begin
ML {*
structure Show_Types = struct
fun pretty_markup_to_string no_markup =
Pretty.string_of
#> YXML.parse_body
#> (if no_markup then XML.content_of else YXML.string_of_body)
fun term_show_types no_markup ctxt term =
let val keywords = Thy_Header.get_keywords' ctxt
val ctxt' = ctxt
|> Config.put show_markup false
|> Config.put Printer.show_type_emphasis false
(* FIXME: the sledgehammer code also sets these,
* but do we always want to force them on the user? *)
(*
|> Config.put show_types false
|> Config.put show_sorts false
|> Config.put show_consts false
*)
|> Variable.auto_fixes term
in
singleton (Syntax.uncheck_terms ctxt') term
|> Sledgehammer_Isar_Annotate.annotate_types_in_term ctxt'
|> Syntax.unparse_term ctxt'
|> pretty_markup_to_string no_markup
end
fun goal_show_types no_markup ctxt goal n = let
val subgoals = goal |> Thm.prems_of
val subgoals = if n = 0 then subgoals else
if n < 1 orelse n > length subgoals then
(* trigger error *) [Logic.get_goal (Thm.term_of (Thm.cprop_of goal)) n]
else [nth subgoals (n - 1)]
val results = map (fn t => (NONE, term_show_types no_markup ctxt t)
handle ex as TERM _ => (SOME ex, term_show_types no_markup ctxt t))
subgoals
in if null results
then error "No subgoals to show"
else if forall (Option.isSome o fst) results
then raise the (fst (hd results))
else map snd results
end
end;
Outer_Syntax.command @{command_keyword term_show_types}
"term_show_types TERM -> show TERM with type annotations"
(Parse.term >> (fn t =>
Toplevel.keep (fn state =>
let val ctxt = Toplevel.context_of state in
Show_Types.term_show_types false ctxt (Syntax.read_term ctxt t)
|> writeln end)));
Outer_Syntax.command @{command_keyword thm_show_types}
"thm_show_types THM1 THM2 ... -> show theorems with type annotations"
(Parse.thms1 >> (fn ts =>
Toplevel.keep (fn state =>
let val ctxt = Toplevel.context_of state in
Attrib.eval_thms ctxt ts
|> app (Thm.prop_of #> Show_Types.term_show_types false ctxt #> writeln) end)));
let
fun print_subgoals (x::xs) n = (writeln (Int.toString n ^ ". " ^ x); print_subgoals xs (n+1))
| print_subgoals [] _ = ();
in
Outer_Syntax.command @{command_keyword goal_show_types}
"goal_show_types [N] -> show subgoals (or Nth goal) with type annotations"
(Scan.option Parse.int >> (fn n =>
Toplevel.keep (fn state =>
let val ctxt = Toplevel.context_of state
val goal = Toplevel.proof_of state |> Proof.raw_goal |> #goal
in Show_Types.goal_show_types false ctxt goal (Option.getOpt (n, 0))
|> (fn xs => case xs of
[x] => writeln x
| _ => print_subgoals xs 1) end)))
end;
*}
text \<open>
Simple demo. The main HOL theories don't have that much
hidden polymorphism, so we use l4.verified.
\<close>
(*
experiment begin
lemma c_guard_cast_byte: "c_guard (x :: ('a :: {mem_type}) ptr) \<Longrightarrow> c_guard (ptr_coerce x :: 8 word ptr)"
goal_show_types 0
using [[show_sorts]]
goal_show_types 0
apply (case_tac x)
apply (fastforce intro!: byte_ptr_guarded simp: c_guard_def dest: c_null_guard)
done
thm c_guard_cast_byte[where x = "Ptr (ucast (0 :: 8 word))"]
thm_show_types c_guard_cast_byte[where x = "Ptr (ucast (0 :: 8 word))"]
(* Round-trip test *)
ML {*
let val ctxt = Config.put show_sorts true @{context}
(* NB: this test fails if we leave some polymorphism in the term *)
val term = @{thm c_guard_cast_byte[where x = "Ptr (ucast (0 :: 8 word)) :: unit ptr"]} |> Thm.prop_of
val string_no_types = Syntax.pretty_term ctxt term
|> Pretty.string_of |> YXML.content_of
val string_show_types = Show_Types.term_show_types true ctxt term
val _ = assert (Syntax.read_term ctxt string_no_types <> term) "Show_Types test (baseline)"
val _ = assert (Syntax.read_term ctxt string_show_types = term) "Show_Types test"
in () end
*}
end
*)
end