src/Tools/Compute_Oracle/linker.ML
author haftmann
Tue, 10 Jul 2007 17:30:50 +0200
changeset 23709 fd31da8f752a
parent 23663 84b5c89b8b49
child 23768 d639647a1ffd
permissions -rw-r--r--
moved lfp_induct2 here
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23663
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     1
(*  Title:      Tools/Compute_Oracle/Linker.ML
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     2
    ID:         $$
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     3
    Author:     Steven Obua
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     4
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     5
    Linker.ML solves the problem that the computing oracle does not instantiate polymorphic rules.
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     6
    By going through the PCompute interface, all possible instantiations are resolved by compiling new programs, if necessary.
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     7
    The obvious disadvantage of this approach is that in the worst case for each new term to be rewritten, a new program may be compiled.
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     8
*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
     9
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    10
(*    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    11
   Given constants/frees c_1::t_1, c_2::t_2, ...., c_n::t_n,
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    12
   and constants/frees d_1::d_1, d_2::s_2, ..., d_m::s_m
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    13
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    14
   Find all substitutions S such that
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    15
   a) the domain of S is tvars (t_1, ..., t_n)   
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    16
   b) there are indices i_1, ..., i_k, and j_1, ..., j_k with
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    17
      1. S (c_i_1::t_i_1) = d_j_1::s_j_1, ..., S (c_i_k::t_i_k) = d_j_k::s_j_k
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    18
      2. tvars (t_i_1, ..., t_i_k) = tvars (t_1, ..., t_n)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    19
*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    20
signature LINKER = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    21
sig
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    22
    exception Link of string
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    23
    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    24
    datatype constant = Constant of bool * string * typ
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    25
    val constant_of : term -> constant
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    26
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    27
    type instances
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    28
    type subst = Type.tyenv
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    29
    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    30
    val empty : constant list -> instances
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    31
    val typ_of_constant : constant -> typ
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    32
    val add_instances : Type.tsig -> instances -> constant list -> subst list * instances
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    33
    val substs_of : instances -> subst list
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    34
    val is_polymorphic : constant -> bool
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    35
    val distinct_constants : constant list -> constant list
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    36
    val collect_consts : term list -> constant list
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    37
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    38
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    39
structure Linker : LINKER = struct
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    40
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    41
exception Link of string;
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    42
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    43
type subst = Type.tyenv
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    44
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    45
datatype constant = Constant of bool * string * typ
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    46
fun constant_of (Const (name, ty)) = Constant (false, name, ty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    47
  | constant_of (Free (name, ty)) = Constant (true, name, ty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    48
  | constant_of _ = raise Link "constant_of"
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    49
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    50
fun bool_ord (x,y) = if x then (if y then EQUAL else GREATER) else (if y then LESS else EQUAL)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    51
fun constant_ord (Constant (x1,x2,x3), Constant (y1,y2,y3)) = (prod_ord (prod_ord bool_ord fast_string_ord) Term.typ_ord) (((x1,x2),x3), ((y1,y2),y3))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    52
fun constant_modty_ord (Constant (x1,x2,_), Constant (y1,y2,_)) = (prod_ord bool_ord fast_string_ord) ((x1,x2), (y1,y2))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    53
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    54
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    55
structure Consttab = TableFun(type key = constant val ord = constant_ord);
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    56
structure ConsttabModTy = TableFun(type key = constant val ord = constant_modty_ord);
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    57
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    58
fun typ_of_constant (Constant (_, _, ty)) = ty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    59
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    60
val empty_subst = (Vartab.empty : Type.tyenv)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    61
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    62
fun merge_subst (A:Type.tyenv) (B:Type.tyenv) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    63
    SOME (Vartab.fold (fn (v, t) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    64
		       fn tab => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    65
			  (case Vartab.lookup tab v of 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    66
			       NONE => Vartab.update (v, t) tab 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    67
			     | SOME t' => if t = t' then tab else raise Type.TYPE_MATCH)) A B)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    68
    handle Type.TYPE_MATCH => NONE
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    69
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    70
fun subst_ord (A:Type.tyenv, B:Type.tyenv) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    71
    (list_ord (prod_ord Term.fast_indexname_ord (prod_ord Term.sort_ord Term.typ_ord))) (Vartab.dest A, Vartab.dest B)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    72
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    73
structure Substtab = TableFun(type key = Type.tyenv val ord = subst_ord);
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    74
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    75
val substtab_union = Substtab.fold Substtab.update
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    76
fun substtab_unions [] = Substtab.empty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    77
  | substtab_unions [c] = c
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    78
  | substtab_unions (c::cs) = substtab_union c (substtab_unions cs)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    79
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    80
datatype instances = Instances of unit ConsttabModTy.table * Type.tyenv Consttab.table Consttab.table * constant list list * unit Substtab.table
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    81
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    82
fun is_polymorphic (Constant (_, _, ty)) = not (null (typ_tvars ty))		
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    83
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    84
fun distinct_constants cs =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    85
    Consttab.keys (fold (fn c => Consttab.update (c, ())) cs Consttab.empty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    86
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    87
fun empty cs = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    88
    let				   
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    89
	val cs = distinct_constants (filter is_polymorphic cs)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    90
	val old_cs = cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    91
(*	fun collect_tvars ty tab = fold (fn v => fn tab => Typtab.update (TVar v, ()) tab) (typ_tvars ty) tab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    92
	val tvars_count = length (Typtab.keys (fold (fn c => fn tab => collect_tvars (typ_of_constant c) tab) cs Typtab.empty))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    93
	fun tvars_of ty = collect_tvars ty Typtab.empty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    94
	val cs = map (fn c => (c, tvars_of (typ_of_constant c))) cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    95
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    96
	fun tyunion A B = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    97
	    Typtab.fold 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    98
		(fn (v,()) => fn tab => Typtab.update (v, case Typtab.lookup tab v of NONE => 1 | SOME n => n+1) tab)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
    99
		A B
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   100
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   101
        fun is_essential A B =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   102
	    Typtab.fold
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   103
	    (fn (v, ()) => fn essential => essential orelse (case Typtab.lookup B v of NONE => raise Link "is_essential" | SOME n => n=1))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   104
	    A false
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   105
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   106
	fun add_minimal (c', tvs') (tvs, cs) =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   107
	    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   108
		val tvs = tyunion tvs' tvs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   109
		val cs = (c', tvs')::cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   110
	    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   111
		if forall (fn (c',tvs') => is_essential tvs' tvs) cs then
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   112
		    SOME (tvs, cs)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   113
		else 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   114
		    NONE
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   115
	    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   116
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   117
	fun is_spanning (tvs, _) = (length (Typtab.keys tvs) = tvars_count)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   118
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   119
	fun generate_minimal_subsets subsets [] = subsets
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   120
	  | generate_minimal_subsets subsets (c::cs) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   121
	    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   122
		val subsets' = map_filter (add_minimal c) subsets
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   123
	    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   124
		generate_minimal_subsets (subsets@subsets') cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   125
	    end*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   126
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   127
	val minimal_subsets = [old_cs] (*map (fn (tvs, cs) => map fst cs) (filter is_spanning (generate_minimal_subsets [(Typtab.empty, [])] cs))*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   128
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   129
	val constants = Consttab.keys (fold (fold (fn c => Consttab.update (c, ()))) minimal_subsets Consttab.empty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   130
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   131
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   132
	Instances (
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   133
	fold (fn c => fn tab => ConsttabModTy.update (c, ()) tab) constants ConsttabModTy.empty,
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   134
	Consttab.make (map (fn c => (c, Consttab.empty : Type.tyenv Consttab.table)) constants), 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   135
	minimal_subsets, Substtab.empty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   136
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   137
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   138
local
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   139
fun calc ctab substtab [] = substtab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   140
  | calc ctab substtab (c::cs) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   141
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   142
	val csubsts = map snd (Consttab.dest (the (Consttab.lookup ctab c)))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   143
	fun merge_substs substtab subst = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   144
	    Substtab.fold (fn (s,_) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   145
			   fn tab => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   146
			      (case merge_subst subst s of NONE => tab | SOME s => Substtab.update (s, ()) tab))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   147
			  substtab Substtab.empty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   148
	val substtab = substtab_unions (map (merge_substs substtab) csubsts)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   149
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   150
	calc ctab substtab cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   151
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   152
in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   153
fun calc_substs ctab (cs:constant list) = calc ctab (Substtab.update (empty_subst, ()) Substtab.empty) cs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   154
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   155
	      			    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   156
fun add_instances tsig (Instances (cfilter, ctab,minsets,substs)) cs = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   157
    let	
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   158
(*	val _ = writeln (makestring ("add_instances: ", length_cs, length cs, length (Consttab.keys ctab)))*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   159
	fun calc_instantiations (constant as Constant (free, name, ty)) instantiations = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   160
	    Consttab.fold (fn (constant' as Constant (free', name', ty'), insttab) =>  
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   161
			   fn instantiations =>
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   162
			      if free <> free' orelse name <> name' then
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   163
				  instantiations
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   164
			      else case Consttab.lookup insttab constant of
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   165
				       SOME _ => instantiations
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   166
				     | NONE => ((constant', (constant, Type.typ_match tsig (ty', ty) empty_subst))::instantiations
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   167
						handle TYPE_MATCH => instantiations))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   168
			  ctab instantiations
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   169
	val instantiations = fold calc_instantiations cs []
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   170
	(*val _ = writeln ("instantiations = "^(makestring (length instantiations)))*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   171
	fun update_ctab (constant', entry) ctab = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   172
	    (case Consttab.lookup ctab constant' of
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   173
		 NONE => raise Link "internal error: update_ctab"
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   174
	       | SOME tab => Consttab.update (constant', Consttab.update entry tab) ctab)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   175
	val ctab = fold update_ctab instantiations ctab	
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   176
	val new_substs = fold (fn minset => fn substs => substtab_union (calc_substs ctab minset) substs) 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   177
			      minsets Substtab.empty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   178
	val (added_substs, substs) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   179
	    Substtab.fold (fn (ns, _) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   180
			   fn (added, substtab) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   181
			      (case Substtab.lookup substs ns of
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   182
				   NONE => (ns::added, Substtab.update (ns, ()) substtab)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   183
				 | SOME () => (added, substtab)))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   184
			  new_substs ([], substs)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   185
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   186
	(added_substs, Instances (cfilter, ctab, minsets, substs))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   187
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   188
	    	
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   189
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   190
fun substs_of (Instances (_,_,_,substs)) = Substtab.keys substs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   191
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   192
local
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   193
    fun get_thm thmname = PureThy.get_thm (theory "Main") (Name thmname)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   194
    val eq_th = get_thm "HOL.eq_reflection"
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   195
in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   196
  fun eq_to_meta th = (eq_th OF [th] handle _ => th)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   197
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   198
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   199
				     
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   200
local
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   201
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   202
fun collect (Var x) tab = tab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   203
  | collect (Bound _) tab = tab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   204
  | collect (a $ b) tab = collect b (collect a tab)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   205
  | collect (Abs (_, _, body)) tab = collect body tab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   206
  | collect t tab = Consttab.update (constant_of t, ()) tab
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   207
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   208
in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   209
  fun collect_consts tms = Consttab.keys (fold collect tms Consttab.empty)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   210
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   211
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   212
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   213
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   214
signature PCOMPUTE =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   215
sig
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   216
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   217
    type pcomputer
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   218
	 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   219
    val make : Compute.machine -> theory -> thm list -> Linker.constant list -> pcomputer
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   220
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   221
(*    val add_thms : pcomputer -> thm list -> bool*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   222
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   223
    val add_instances : pcomputer -> Linker.constant list -> bool 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   224
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   225
    val rewrite : pcomputer -> cterm list -> thm list
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   226
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   227
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   228
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   229
structure PCompute : PCOMPUTE = struct
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   230
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   231
exception PCompute of string
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   232
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   233
datatype theorem = MonoThm of thm | PolyThm of thm * Linker.instances * thm list
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   234
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   235
datatype pcomputer = PComputer of Compute.machine * theory_ref * Compute.computer ref * theorem list ref
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   236
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   237
(*fun collect_consts (Var x) = []
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   238
  | collect_consts (Bound _) = []
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   239
  | collect_consts (a $ b) = (collect_consts a)@(collect_consts b)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   240
  | collect_consts (Abs (_, _, body)) = collect_consts body
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   241
  | collect_consts t = [Linker.constant_of t]*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   242
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   243
fun collect_consts_of_thm th = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   244
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   245
	val th = prop_of th
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   246
	val (prems, th) = (Logic.strip_imp_prems th, Logic.strip_imp_concl th)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   247
	val (left, right) = Logic.dest_equals th
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   248
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   249
	(Linker.collect_consts [left], Linker.collect_consts (right::prems))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   250
    end 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   251
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   252
fun create_theorem th =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   253
let    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   254
    val (left, right) = collect_consts_of_thm th
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   255
    val polycs = filter Linker.is_polymorphic left
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   256
    val tytab = fold (fn p => fn tab => fold (fn n => fn tab => Typtab.update (TVar n, ()) tab) (typ_tvars (Linker.typ_of_constant p)) tab) polycs Typtab.empty
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   257
    fun check_const (c::cs) cs' = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   258
	let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   259
	    val tvars = typ_tvars (Linker.typ_of_constant c)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   260
	    val wrong = fold (fn n => fn wrong => wrong orelse is_none (Typtab.lookup tytab (TVar n))) tvars false
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   261
	in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   262
	    if wrong then raise PCompute "right hand side of theorem contains type variables which do not occur on the left hand side"
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   263
	    else 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   264
		if null (tvars) then
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   265
		    check_const cs (c::cs')
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   266
		else
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   267
		    check_const cs cs'
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   268
	end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   269
      | check_const [] cs' = cs'
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   270
    val monocs = check_const right [] 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   271
in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   272
    if null (polycs) then 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   273
	(monocs, MonoThm th)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   274
    else
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   275
	(monocs, PolyThm (th, Linker.empty polycs, []))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   276
end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   277
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   278
fun create_computer machine thy ths = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   279
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   280
	fun add (MonoThm th) ths = th::ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   281
	  | add (PolyThm (_, _, ths')) ths = ths'@ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   282
	val ths = fold_rev add ths []
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   283
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   284
	Compute.make machine thy ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   285
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   286
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   287
fun conv_subst thy (subst : Type.tyenv) =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   288
    map (fn (iname, (sort, ty)) => (ctyp_of thy (TVar (iname, sort)), ctyp_of thy ty)) (Vartab.dest subst)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   289
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   290
fun add_monos thy monocs ths = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   291
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   292
	val tsig = Sign.tsig_of thy
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   293
	val changed = ref false
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   294
	fun add monocs (th as (MonoThm _)) = ([], th)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   295
	  | add monocs (PolyThm (th, instances, instanceths)) = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   296
	    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   297
		val (newsubsts, instances) = Linker.add_instances tsig instances monocs
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   298
		val _ = if not (null newsubsts) then changed := true else ()
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   299
		val newths = map (fn subst => Thm.instantiate (conv_subst thy subst, []) th) newsubsts
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   300
(*		val _ = if not (null newths) then (print ("added new theorems: ", newths); ()) else ()*)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   301
		val newmonos = fold (fn th => fn monos => (snd (collect_consts_of_thm th))@monos) newths []
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   302
	    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   303
		(newmonos, PolyThm (th, instances, instanceths@newths))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   304
	    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   305
	fun step monocs ths = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   306
	    fold_rev (fn th => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   307
		      fn (newmonos, ths) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   308
			 let val (newmonos', th') = add monocs th in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   309
			     (newmonos'@newmonos, th'::ths)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   310
			 end)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   311
		     ths ([], [])
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   312
	fun loop monocs ths = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   313
	    let val (monocs', ths') = step monocs ths in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   314
		if null (monocs') then 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   315
		    ths' 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   316
		else 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   317
		    loop monocs' ths'
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   318
	    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   319
	val result = loop monocs ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   320
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   321
	(!changed, result)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   322
    end	    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   323
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   324
datatype cthm = ComputeThm of term list * sort list * term
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   325
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   326
fun thm2cthm th = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   327
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   328
	val {hyps, prop, shyps, ...} = Thm.rep_thm th
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   329
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   330
	ComputeThm (hyps, shyps, prop)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   331
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   332
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   333
val cthm_ord' = prod_ord (prod_ord (list_ord Term.term_ord) (list_ord Term.sort_ord)) Term.term_ord
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   334
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   335
fun cthm_ord (ComputeThm (h1, sh1, p1), ComputeThm (h2, sh2, p2)) = cthm_ord' (((h1,sh1), p1), ((h2, sh2), p2))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   336
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   337
structure CThmtab = TableFun (type key = cthm val ord = cthm_ord)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   338
    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   339
fun remove_duplicates ths =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   340
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   341
	val counter = ref 0 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   342
	val tab = ref (CThmtab.empty : unit CThmtab.table)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   343
	val thstab = ref (Inttab.empty : thm Inttab.table)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   344
	fun update th = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   345
	    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   346
		val key = thm2cthm th
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   347
	    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   348
		case CThmtab.lookup (!tab) key of
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   349
		    NONE => ((tab := CThmtab.update_new (key, ()) (!tab)); thstab := Inttab.update_new (!counter, th) (!thstab); counter := !counter + 1)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   350
		  | _ => ()
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   351
	    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   352
	val _ = map update ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   353
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   354
	map snd (Inttab.dest (!thstab))
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   355
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   356
    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   357
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   358
fun make machine thy ths cs =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   359
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   360
	val ths = remove_duplicates ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   361
	val (monocs, ths) = fold_rev (fn th => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   362
				      fn (monocs, ths) => 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   363
					 let val (m, t) = create_theorem th in 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   364
					     (m@monocs, t::ths)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   365
					 end)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   366
				     ths (cs, [])
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   367
	val (_, ths) = add_monos thy monocs ths
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   368
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   369
	PComputer (machine, Theory.self_ref thy, ref (create_computer machine thy ths), ref ths)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   370
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   371
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   372
fun add_instances (PComputer (machine, thyref, rcomputer, rths)) cs = 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   373
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   374
	val thy = Theory.deref thyref
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   375
	val (changed, ths) = add_monos thy cs (!rths)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   376
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   377
	if changed then 
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   378
	    (rcomputer := create_computer machine thy ths;
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   379
	     rths := ths;
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   380
	     true)
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   381
	else
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   382
	    false
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   383
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   384
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   385
fun rewrite (pc as PComputer (_, _, rcomputer, _)) cts =
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   386
    let
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   387
	val _ = map (fn ct => add_instances pc (Linker.collect_consts [term_of ct])) cts
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   388
    in
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   389
	map (fn ct => Compute.rewrite (!rcomputer) ct) cts
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   390
    end
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   391
		 							      			    
84b5c89b8b49 new version of computing oracle
obua
parents:
diff changeset
   392
end