src/HOL/Matrix_LP/Compute_Oracle/compute.ML
changeset 77863 760515c45864
parent 77808 b43ee37926a9
child 77869 1156aa9db7f5
equal deleted inserted replaced
77862:cba7246c2c32 77863:760515c45864
    14 
    14 
    15     exception Make of string
    15     exception Make of string
    16     val make : machine -> theory -> thm list -> computer
    16     val make : machine -> theory -> thm list -> computer
    17     val make_with_cache : machine -> theory -> term list -> thm list -> computer
    17     val make_with_cache : machine -> theory -> term list -> thm list -> computer
    18     val theory_of : computer -> theory
    18     val theory_of : computer -> theory
    19     val hyps_of : computer -> Termset.T
    19     val hyps_of : computer -> term list
    20     val shyps_of : computer -> Sortset.T
    20     val shyps_of : computer -> Sortset.T
    21     (* ! *) val update : computer -> thm list -> unit
    21     (* ! *) val update : computer -> thm list -> unit
    22     (* ! *) val update_with_cache : computer -> term list -> thm list -> unit
    22     (* ! *) val update_with_cache : computer -> term list -> thm list -> unit
    23     
    23     
    24     (* ! *) val set_naming : computer -> naming -> unit
    24     (* ! *) val set_naming : computer -> naming -> unit
   167 type naming = int -> string
   167 type naming = int -> string
   168 
   168 
   169 fun default_naming i = "v_" ^ string_of_int i
   169 fun default_naming i = "v_" ^ string_of_int i
   170 
   170 
   171 datatype computer = Computer of
   171 datatype computer = Computer of
   172   (theory * Encode.encoding * Termset.T * Sortset.T * prog * unit Unsynchronized.ref * naming)
   172   (theory * Encode.encoding * term list * Sortset.T * prog * unit Unsynchronized.ref * naming)
   173     option Unsynchronized.ref
   173     option Unsynchronized.ref
   174 
   174 
   175 fun theory_of (Computer (Unsynchronized.ref (SOME (thy,_,_,_,_,_,_)))) = thy
   175 fun theory_of (Computer (Unsynchronized.ref (SOME (thy,_,_,_,_,_,_)))) = thy
   176 fun hyps_of (Computer (Unsynchronized.ref (SOME (_,_,hyps,_,_,_,_)))) = hyps
   176 fun hyps_of (Computer (Unsynchronized.ref (SOME (_,_,hyps,_,_,_,_)))) = hyps
   177 fun shyps_of (Computer (Unsynchronized.ref (SOME (_,_,_,shypset,_,_,_)))) = shypset
   177 fun shyps_of (Computer (Unsynchronized.ref (SOME (_,_,_,shypset,_,_,_)))) = shypset
   185     (r := SOME (p1,p2,p3,p4,p5,p6,naming'))
   185     (r := SOME (p1,p2,p3,p4,p5,p6,naming'))
   186 
   186 
   187 fun ref_of (Computer r) = r
   187 fun ref_of (Computer r) = r
   188 
   188 
   189 
   189 
   190 datatype cthm = ComputeThm of Termset.T * Sortset.T * term
   190 datatype cthm = ComputeThm of term list * Sortset.T * term
   191 
   191 
   192 fun thm2cthm th = 
   192 fun thm2cthm th = 
   193     (if not (null (Thm.tpairs_of th)) then raise Make "theorems may not contain tpairs" else ();
   193     (if not (null (Thm.tpairs_of th)) then raise Make "theorems may not contain tpairs" else ();
   194      ComputeThm (Thm.hyps_of th, Thm.shyps_of th, Thm.prop_of th))
   194      ComputeThm (Thm.hyps_of th, Thm.shyps_of th, Thm.prop_of th))
   195 
   195 
   217                     raise (Make "patterns may not start with a variable")
   217                     raise (Make "patterns may not start with a variable")
   218                   | AbstractMachine.PConst (c, args) =>
   218                   | AbstractMachine.PConst (c, args) =>
   219                     (n, vars, AbstractMachine.PConst (c, args@[pb]))
   219                     (n, vars, AbstractMachine.PConst (c, args@[pb]))
   220             end
   220             end
   221 
   221 
   222         fun thm2rule (encoding, hypset, shypset) th =
   222         fun thm2rule (encoding, hyptable, shypset) th =
   223             let
   223             let
   224                 val (ComputeThm (hyps, shyps, prop)) = th
   224                 val (ComputeThm (hyps, shyps, prop)) = th
   225                 val hypset = Termset.merge (hyps, hypset)
   225                 val hyptable = fold (fn h => Termtab.update (h, ())) hyps hyptable
   226                 val shypset = Sortset.merge (shyps, shypset)
   226                 val shypset = Sortset.merge (shyps, shypset)
   227                 val (prems, prop) = (Logic.strip_imp_prems prop, Logic.strip_imp_concl prop)
   227                 val (prems, prop) = (Logic.strip_imp_prems prop, Logic.strip_imp_concl prop)
   228                 val (a, b) = Logic.dest_equals prop
   228                 val (a, b) = Logic.dest_equals prop
   229                   handle TERM _ => raise (Make "theorems must be meta-level equations (with optional guards)")
   229                   handle TERM _ => raise (Make "theorems must be meta-level equations (with optional guards)")
   230                 val a = Envir.eta_contract a
   230                 val a = Envir.eta_contract a
   267                     AbstractMachine.Abs (rename (level+1) vars m)
   267                     AbstractMachine.Abs (rename (level+1) vars m)
   268                     
   268                     
   269                 fun rename_guard (AbstractMachine.Guard (a,b)) = 
   269                 fun rename_guard (AbstractMachine.Guard (a,b)) = 
   270                     AbstractMachine.Guard (rename 0 vars a, rename 0 vars b)
   270                     AbstractMachine.Guard (rename 0 vars a, rename 0 vars b)
   271             in
   271             in
   272                 ((encoding, hypset, shypset), (map rename_guard prems, pattern, rename 0 vars right))
   272                 ((encoding, hyptable, shypset), (map rename_guard prems, pattern, rename 0 vars right))
   273             end
   273             end
   274 
   274 
   275         val ((encoding, hypset, shypset), rules) =
   275         val ((encoding, hyptable, shypset), rules) =
   276           fold_rev (fn th => fn (encoding_hypset, rules) =>
   276           fold_rev (fn th => fn (encoding_hyptable, rules) =>
   277             let
   277             let
   278               val (encoding_hypset, rule) = thm2rule encoding_hypset th
   278               val (encoding_hyptable, rule) = thm2rule encoding_hyptable th
   279             in (encoding_hypset, rule::rules) end)
   279             in (encoding_hyptable, rule::rules) end)
   280           ths ((encoding, Termset.empty, Sortset.empty), [])
   280           ths ((encoding, Termtab.empty, Sortset.empty), [])
   281 
   281 
   282         fun make_cache_pattern t (encoding, cache_patterns) =
   282         fun make_cache_pattern t (encoding, cache_patterns) =
   283             let
   283             let
   284                 val (encoding, a) = remove_types encoding t
   284                 val (encoding, a) = remove_types encoding t
   285                 val (_,_,p) = make_pattern encoding 0 Inttab.empty a
   285                 val (_,_,p) = make_pattern encoding 0 Inttab.empty a
   286             in
   286             in
   287                 (encoding, p::cache_patterns)
   287                 (encoding, p::cache_patterns)
   288             end
   288             end
   289         
   289         
   290         val (encoding, _) = Termset.fold_rev make_cache_pattern cache_pattern_terms (encoding, [])
   290         val (encoding, _) = fold_rev make_cache_pattern cache_pattern_terms (encoding, [])
   291 
   291 
   292         val prog = 
   292         val prog = 
   293             case machine of 
   293             case machine of 
   294                 BARRAS => ProgBarras (AM_Interpreter.compile rules)
   294                 BARRAS => ProgBarras (AM_Interpreter.compile rules)
   295               | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile rules)
   295               | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile rules)
   298 
   298 
   299         fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   299         fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   300 
   300 
   301         val shypset = Sortset.fold (fn s => has_witness s ? Sortset.remove s) shypset shypset
   301         val shypset = Sortset.fold (fn s => has_witness s ? Sortset.remove s) shypset shypset
   302 
   302 
   303     in (thy, encoding, hypset, shypset, prog, stamp, default_naming) end
   303     in (thy, encoding, Termtab.keys hyptable, shypset, prog, stamp, default_naming) end
   304 
   304 
   305 fun make_with_cache machine thy cache_patterns raw_thms =
   305 fun make_with_cache machine thy cache_patterns raw_thms =
   306   Computer (Unsynchronized.ref
   306   Computer (Unsynchronized.ref (SOME (make_internal machine thy (Unsynchronized.ref ()) Encode.empty cache_patterns raw_thms)))
   307     (SOME (make_internal machine thy (Unsynchronized.ref ()) Encode.empty (Termset.make cache_patterns) raw_thms)))
       
   308 
   307 
   309 fun make machine thy raw_thms = make_with_cache machine thy [] raw_thms
   308 fun make machine thy raw_thms = make_with_cache machine thy [] raw_thms
   310 
   309 
   311 fun update_with_cache computer cache_patterns raw_thms =
   310 fun update_with_cache computer cache_patterns raw_thms =
   312     let 
   311     let 
   313         val c = make_internal (machine_of_prog (prog_of computer)) (theory_of computer) (stamp_of computer) 
   312         val c = make_internal (machine_of_prog (prog_of computer)) (theory_of computer) (stamp_of computer) 
   314                               (encoding_of computer) (Termset.make cache_patterns) raw_thms
   313                               (encoding_of computer) cache_patterns raw_thms
   315         val _ = (ref_of computer) := SOME c     
   314         val _ = (ref_of computer) := SOME c     
   316     in
   315     in
   317         ()
   316         ()
   318     end
   317     end
   319 
   318 
   325   | runprog (ProgSML p) = AM_SML.run p    
   324   | runprog (ProgSML p) = AM_SML.run p    
   326 
   325 
   327 (* ------------------------------------------------------------------------------------- *)
   326 (* ------------------------------------------------------------------------------------- *)
   328 (* An oracle for exporting theorems; must only be accessible from inside this structure! *)
   327 (* An oracle for exporting theorems; must only be accessible from inside this structure! *)
   329 (* ------------------------------------------------------------------------------------- *)
   328 (* ------------------------------------------------------------------------------------- *)
       
   329 
       
   330 fun merge_hyps hyps1 hyps2 = 
       
   331 let
       
   332     fun add hyps tab = fold (fn h => fn tab => Termtab.update (h, ()) tab) hyps tab
       
   333 in
       
   334     Termtab.keys (add hyps2 (add hyps1 Termtab.empty))
       
   335 end
   330 
   336 
   331 val (_, export_oracle) = Context.>>> (Context.map_theory_result
   337 val (_, export_oracle) = Context.>>> (Context.map_theory_result
   332   (Thm.add_oracle (\<^binding>\<open>compute\<close>, fn (thy, hyps, shyps, prop) =>
   338   (Thm.add_oracle (\<^binding>\<open>compute\<close>, fn (thy, hyps, shyps, prop) =>
   333     let
   339     let
   334         fun remove_term t = Sortset.subtract (Sortset.build (Sortset.insert_term t))
   340         fun remove_term t = Sortset.subtract (Sortset.build (Sortset.insert_term t))
   366         val (encoding, t) = remove_types (encoding_of computer) t'
   372         val (encoding, t) = remove_types (encoding_of computer) t'
   367         val t = runprog (prog_of computer) t
   373         val t = runprog (prog_of computer) t
   368         val t = infer_types naming encoding ty t
   374         val t = infer_types naming encoding ty t
   369         val eq = Logic.mk_equals (t', t)
   375         val eq = Logic.mk_equals (t', t)
   370     in
   376     in
   371         export_thm thy (Termset.dest (hyps_of computer)) (shyps_of computer) eq
   377         export_thm thy (hyps_of computer) (shyps_of computer) eq
   372     end
   378     end
   373 
   379 
   374 (* --------- Simplify ------------ *)
   380 (* --------- Simplify ------------ *)
   375 
   381 
   376 datatype prem = EqPrem of AbstractMachine.term * AbstractMachine.term * Term.typ * int 
   382 datatype prem = EqPrem of AbstractMachine.term * AbstractMachine.term * Term.typ * int 
   377               | Prem of AbstractMachine.term
   383               | Prem of AbstractMachine.term
   378 datatype theorem = Theorem of theory * unit Unsynchronized.ref * (int * typ) Symtab.table * (AbstractMachine.term option) Inttab.table  
   384 datatype theorem = Theorem of theory * unit Unsynchronized.ref * (int * typ) Symtab.table * (AbstractMachine.term option) Inttab.table  
   379                * prem list * AbstractMachine.term * Termset.T * Sortset.T
   385                * prem list * AbstractMachine.term * term list * Sortset.T
   380 
   386 
   381 
   387 
   382 exception ParamSimplify of computer * theorem
   388 exception ParamSimplify of computer * theorem
   383 
   389 
   384 fun make_theorem computer raw_th vars =
   390 fun make_theorem computer raw_th vars =
   605         NONE => raise Compute "modus_ponens: conclusion does not match premise"
   611         NONE => raise Compute "modus_ponens: conclusion does not match premise"
   606       | SOME varsubst =>
   612       | SOME varsubst =>
   607         let
   613         let
   608             val th = update_varsubst varsubst th
   614             val th = update_varsubst varsubst th
   609             val th = update_prems (splicein prem_no (prems_of_theorem th') prems) th
   615             val th = update_prems (splicein prem_no (prems_of_theorem th') prems) th
   610             val th = update_hyps (Termset.merge (hyps_of_theorem th, hyps_of_theorem th')) th
   616             val th = update_hyps (merge_hyps (hyps_of_theorem th) (hyps_of_theorem th')) th
   611             val th = update_shyps (Sortset.merge (shyps_of_theorem th, shyps_of_theorem th')) th
   617             val th = update_shyps (Sortset.merge (shyps_of_theorem th, shyps_of_theorem th')) th
   612         in
   618         in
   613             update_theory thy th
   619             update_theory thy th
   614         end
   620         end
   615 end
   621 end
   622     val naming = naming_of computer
   628     val naming = naming_of computer
   623     fun infer t = infer_types naming encoding \<^typ>\<open>prop\<close> t
   629     fun infer t = infer_types naming encoding \<^typ>\<open>prop\<close> t
   624     fun run t = infer (runprog (prog_of computer) (apply_subst true varsubst t))
   630     fun run t = infer (runprog (prog_of computer) (apply_subst true varsubst t))
   625     fun runprem p = run (prem2term p)
   631     fun runprem p = run (prem2term p)
   626     val prop = Logic.list_implies (map runprem (prems_of_theorem th), run (concl_of_theorem th))
   632     val prop = Logic.list_implies (map runprem (prems_of_theorem th), run (concl_of_theorem th))
   627     val hyps = Termset.merge (hyps_of computer, hyps_of_theorem th)
   633     val hyps = merge_hyps (hyps_of computer) (hyps_of_theorem th)
   628     val shyps = Sortset.merge (shyps_of_theorem th, shyps_of computer)
   634     val shyps = Sortset.merge (shyps_of_theorem th, shyps_of computer)
   629 in
   635 in
   630     export_thm (theory_of_theorem th) (Termset.dest hyps) shyps prop
   636     export_thm (theory_of_theorem th) hyps shyps prop
   631 end
   637 end
   632 
   638 
   633 end
   639 end