summaryrefslogtreecommitdiff
path: root/backends/hol4/saveThmsLib.sml
blob: d2523eeb638d94634360253d211ec7f0c0b00e32 (plain)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
structure saveThmsLib =
struct

type simpset = simpLib.simpset;

open HolKernel boolLib markerLib;

val op++ = simpLib.++;
val op-* = simpLib.-*;

val ERR = mk_HOL_ERR "saveThmsLib";

fun add_simpls tyinfo ss =
    (ss ++ simpLib.tyi_to_ssdata tyinfo) handle HOL_ERR _ => ss

(* TODO: what is this? *)
fun tyinfol() = TypeBasePure.listItems (TypeBase.theTypeBase())

datatype stc_update = ADD_SSFRAG of simpLib.ssfrag | REMOVE_RWT of string
type stc_state = simpset * bool * stc_update list
  (* theorems, initialised-flag, update list (most recent first) *)

val initial_simpset = simpLib.empty_ss
fun ssf1 nth = simpLib.empty_ssfrag |> simpLib.add_named_rwt nth

val state0 : stc_state = (initial_simpset, false, [])
fun apply_delta d ((sset,initp,upds):stc_state) : stc_state =
    case d of
        ThmSetData.ADD nth =>
        (sset ++ ssf1 nth, true, [])
      | ThmSetData.REMOVE s => (sset -* [s], true, [])

fun apply_stc_update (ADD_SSFRAG ssf, ss) = ss ++ ssf
  | apply_stc_update (REMOVE_RWT n, ss) = ss -* [n]

(* A stateful theorems collection *)
datatype stc = STC_CON of {
    name        : string,
    thy_ssfrag  : string -> simpLib.ssfrag,
    thy_simpset : string -> simpset option,
    get_ss      : unit -> simpset,
    export_thms : string list -> unit
}

(* Create a stateful theorems collection *)
fun create_stateful_theorem_set (stc_name : string) =
  let
(* val stc_name = "testStc" *)

    fun init_state (st as (sset,initp,upds)) =
        if initp then st
        else
          let fun init() =
                  (List.foldl apply_stc_update sset (List.rev upds)
                              |> rev_itlist add_simpls (tyinfol()),
                   true, [])
          in
            HOL_PROGRESS_MESG ("Initialising STC simpset: " ^ stc_name ^ " ... ", "done") init ()
          end

    fun opt_partition f g ls =
        let
          fun recurse As Bs ls =
              case ls of
                  [] => (List.rev As, List.rev Bs)
                | h::t => (case f h of
                               SOME a => recurse (a::As) Bs t
                             | NONE => (case g h of
                                            SOME b => recurse As (b::Bs) t
                                         | NONE => recurse As Bs t))
        in
          recurse [] [] ls
        end

    (* stale-ness is important for derived values. Derived values will get
       re-calculated if their flag is true when the value is requested.
    *)
    val stale_flags = Sref.new ([] : bool Sref.t list)
    fun notify () =
        List.app (fn br => Sref.update br (K true)) (Sref.value stale_flags)

    fun apply_to_global d (st as (sset,initp,upds):stc_state) : stc_state =
        if not initp then
          case d of
              ThmSetData.ADD nth =>
              let
                open simpLib
                val upds' =
                    case upds of
                        ADD_SSFRAG ssf :: rest =>
                        ADD_SSFRAG (add_named_rwt nth ssf) :: rest
                      | _ => ADD_SSFRAG (ssf1 nth) :: upds
              in
                (sset, initp, upds')
              end
            | ThmSetData.REMOVE s => (sset, initp, REMOVE_RWT s :: upds)
        else
          apply_delta d st before notify()

    fun finaliser {thyname} deltas (sset,initp,upds) =
      let
        fun toNamedAdd (ThmSetData.ADD p) = SOME p | toNamedAdd _ = NONE
        fun toRM (ThmSetData.REMOVE s) = SOME s | toRM _ = NONE
        val (adds,rms) = opt_partition toNamedAdd toRM deltas
        val ssfrag = simpLib.named_rewrites_with_names thyname (List.rev adds)
          (* List.rev here preserves old behaviour wrt to the way theorems were
             added to the global simpset; it will only make a difference when
             overall rewrite system is not confluent *)
        val new_upds = ADD_SSFRAG ssfrag :: map REMOVE_RWT rms
      in
        if initp then
          (List.foldl apply_stc_update sset new_upds, true, []) before notify()
        else (sset, false, List.revAppend(new_upds, upds))
      end


    val adresult as {DB,get_global_value,record_delta,update_global_value,...} =
      ThmSetData.export_with_ancestry {
        delta_ops = {
          apply_delta = apply_delta,
          apply_to_global = apply_to_global,
          thy_finaliser = SOME finaliser,
          initial_value = state0, uptodate_delta = K true
        },
        settype = stc_name
      }

    val get_deltas = #get_deltas adresult

    (*
    (* TODO: what is this? *)
    fun update_fn tyi =
      augment_stc_ss ([simpLib.tyi_to_ssdata tyi] handle HOL_ERR _ => [])

    val () = TypeBase.register_update_fn (fn tyi => (update_fn tyi; tyi))
    *)

    fun get_ss () =
        (update_global_value init_state;
         #1 (get_global_value()))

    fun export_thms slist =
      let val ds = map ThmSetData.mk_add slist
      in
        List.app record_delta ds;
        update_global_value (rev_itlist apply_to_global ds)
      end

    (* assume that there aren't any removes for things added in this theory;
       it's not rational to do that; one should add it locally only, or not
       add it at all
    *)
    fun mkfrag_from thy setdeltas =
      let fun recurse ADDs [] = ADDs
            | recurse ADDs (ThmSetData.ADD p :: rest) = recurse (p::ADDs) rest
            | recurse ADDs (_ :: rest) = recurse ADDs rest
          val ADDs = recurse [] setdeltas
            (* order of addition is flipped; see above for why this is
               "reasonable" *)
      in
        simpLib.named_rewrites_with_names thy ADDs
      end
    fun thy_ssfrag s = get_deltas {thyname=s} |> mkfrag_from s

    fun thy_simpset s = Option.map (#1 o init_state) (DB {thyname=s})
  in
    STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset,
              get_ss = get_ss, export_thms = export_thms }
  end

fun rewrite_thms_of_simpset (ss : simpset) : thm list =
  List.concat (map simpLib.frag_rewrites (simpLib.ssfrags_of ss))

(*
(* Create a stateful theorems collection *)
val STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset, get_ss = get_ss, export_thms = export_thms } =
  create_stateful_theorem_set "testStc1"

Theorem th1:
  T /\ (T /\ T)
Proof
  fs []
QED

export_thms ["th1"]

fun rewrite_thms_of_simpset (ss : simpset) : thm list =
  List.concat (map simpLib.frag_rewrites (simpLib.ssfrags_of ss))

rewrite_thms_of_simpset (get_ss ())
*)

val STC_CON { name = stc_name, thy_ssfrag = thy_ssfrag, thy_simpset = thy_simpset, get_ss = get_ss, export_thms = export_thms } =
  create_stateful_theorem_set "testStc1"

end