src/HOL/Orderings.thy
changeset 56508 af08160c5a4c
parent 56020 f92479477c52
child 56509 e050d42dc21d
equal deleted inserted replaced
56507:5f6f2576a836 56508:af08160c5a4c
   342 
   342 
   343 
   343 
   344 subsection {* Reasoning tools setup *}
   344 subsection {* Reasoning tools setup *}
   345 
   345 
   346 ML {*
   346 ML {*
   347 
       
   348 signature ORDERS =
   347 signature ORDERS =
   349 sig
   348 sig
   350   val print_structures: Proof.context -> unit
   349   val print_structures: Proof.context -> unit
   351   val attrib_setup: theory -> theory
       
   352   val order_tac: Proof.context -> thm list -> int -> tactic
   350   val order_tac: Proof.context -> thm list -> int -> tactic
   353 end;
   351 end;
   354 
   352 
   355 structure Orders: ORDERS =
   353 structure Orders: ORDERS =
   356 struct
   354 struct
   357 
   355 
   358 (** Theory and context data **)
   356 (* context data *)
   359 
   357 
   360 fun struct_eq ((s1: string, ts1), (s2, ts2)) =
   358 fun struct_eq ((s1: string, ts1), (s2, ts2)) =
   361   (s1 = s2) andalso eq_list (op aconv) (ts1, ts2);
   359   s1 = s2 andalso eq_list (op aconv) (ts1, ts2);
   362 
   360 
   363 structure Data = Generic_Data
   361 structure Data = Generic_Data
   364 (
   362 (
   365   type T = ((string * term list) * Order_Tac.less_arith) list;
   363   type T = ((string * term list) * Order_Tac.less_arith) list;
   366     (* Order structures:
   364     (* Order structures:
   384        Pretty.enclose "(" ")" (Pretty.breaks (map pretty_term ts))];
   382        Pretty.enclose "(" ")" (Pretty.breaks (map pretty_term ts))];
   385   in
   383   in
   386     Pretty.writeln (Pretty.big_list "order structures:" (map pretty_struct structs))
   384     Pretty.writeln (Pretty.big_list "order structures:" (map pretty_struct structs))
   387   end;
   385   end;
   388 
   386 
   389 
   387 val _ =
   390 (** Method **)
   388   Outer_Syntax.improper_command @{command_spec "print_orders"}
   391 
   389     "print order structures available to transitivity reasoner"
   392 fun struct_tac ((s, [eq, le, less]), thms) ctxt prems =
   390     (Scan.succeed (Toplevel.unknown_context o
       
   391       Toplevel.keep (print_structures o Toplevel.context_of)));
       
   392 
       
   393 
       
   394 (* tactics *)
       
   395 
       
   396 fun struct_tac ((s, ops), thms) ctxt facts =
   393   let
   397   let
       
   398     val [eq, le, less] = ops;
   394     fun decomp thy (@{const Trueprop} $ t) =
   399     fun decomp thy (@{const Trueprop} $ t) =
   395       let
   400           let
   396         fun excluded t =
   401             fun excluded t =
   397           (* exclude numeric types: linear arithmetic subsumes transitivity *)
   402               (* exclude numeric types: linear arithmetic subsumes transitivity *)
   398           let val T = type_of t
   403               let val T = type_of t
   399           in
   404               in
   400             T = HOLogic.natT orelse T = HOLogic.intT orelse T = HOLogic.realT
   405                 T = HOLogic.natT orelse T = HOLogic.intT orelse T = HOLogic.realT
   401           end;
   406               end;
   402         fun rel (bin_op $ t1 $ t2) =
   407             fun rel (bin_op $ t1 $ t2) =
   403               if excluded t1 then NONE
   408                   if excluded t1 then NONE
   404               else if Pattern.matches thy (eq, bin_op) then SOME (t1, "=", t2)
   409                   else if Pattern.matches thy (eq, bin_op) then SOME (t1, "=", t2)
   405               else if Pattern.matches thy (le, bin_op) then SOME (t1, "<=", t2)
   410                   else if Pattern.matches thy (le, bin_op) then SOME (t1, "<=", t2)
   406               else if Pattern.matches thy (less, bin_op) then SOME (t1, "<", t2)
   411                   else if Pattern.matches thy (less, bin_op) then SOME (t1, "<", t2)
   407               else NONE
   412                   else NONE
   408           | rel _ = NONE;
   413               | rel _ = NONE;
   409         fun dec (Const (@{const_name Not}, _) $ t) = (case rel t
   414             fun dec (Const (@{const_name Not}, _) $ t) =
   410               of NONE => NONE
   415                   (case rel t of NONE =>
   411                | SOME (t1, rel, t2) => SOME (t1, "~" ^ rel, t2))
   416                     NONE
   412           | dec x = rel x;
   417                   | SOME (t1, rel, t2) => SOME (t1, "~" ^ rel, t2))
   413       in dec t end
   418               | dec x = rel x;
   414       | decomp thy _ = NONE;
   419           in dec t end
       
   420       | decomp _ _ = NONE;
   415   in
   421   in
   416     case s of
   422     (case s of
   417       "order" => Order_Tac.partial_tac decomp thms ctxt prems
   423       "order" => Order_Tac.partial_tac decomp thms ctxt facts
   418     | "linorder" => Order_Tac.linear_tac decomp thms ctxt prems
   424     | "linorder" => Order_Tac.linear_tac decomp thms ctxt facts
   419     | _ => error ("Unknown kind of order `" ^ s ^ "' encountered in transitivity reasoner.")
   425     | _ => error ("Unknown order kind " ^ quote s ^ " encountered in transitivity reasoner"))
   420   end
   426   end
   421 
   427 
   422 fun order_tac ctxt prems =
   428 fun order_tac ctxt facts =
   423   FIRST' (map (fn s => CHANGED o struct_tac s ctxt prems) (Data.get (Context.Proof ctxt)));
   429   FIRST' (map (fn s => CHANGED o struct_tac s ctxt facts) (Data.get (Context.Proof ctxt)));
   424 
   430 
   425 
   431 
   426 (** Attribute **)
   432 (* attributes *)
   427 
   433 
   428 fun add_struct_thm s tag =
   434 fun add_struct_thm s tag =
   429   Thm.declaration_attribute
   435   Thm.declaration_attribute
   430     (fn thm => Data.map (AList.map_default struct_eq (s, Order_Tac.empty TrueI) (Order_Tac.update tag thm)));
   436     (fn thm => Data.map (AList.map_default struct_eq (s, Order_Tac.empty TrueI) (Order_Tac.update tag thm)));
   431 fun del_struct s =
   437 fun del_struct s =
   432   Thm.declaration_attribute
   438   Thm.declaration_attribute
   433     (fn _ => Data.map (AList.delete struct_eq s));
   439     (fn _ => Data.map (AList.delete struct_eq s));
   434 
   440 
   435 val attrib_setup =
       
   436   Attrib.setup @{binding order}
       
   437     (Scan.lift ((Args.add -- Args.name >> (fn (_, s) => SOME s) || Args.del >> K NONE) --|
       
   438       Args.colon (* FIXME || Scan.succeed true *) ) -- Scan.lift Args.name --
       
   439       Scan.repeat Args.term
       
   440       >> (fn ((SOME tag, n), ts) => add_struct_thm (n, ts) tag
       
   441            | ((NONE, n), ts) => del_struct (n, ts)))
       
   442     "theorems controlling transitivity reasoner";
       
   443 
       
   444 
       
   445 (** Diagnostic command **)
       
   446 
       
   447 val _ =
   441 val _ =
   448   Outer_Syntax.improper_command @{command_spec "print_orders"}
   442   Theory.setup
   449     "print order structures available to transitivity reasoner"
   443     (Attrib.setup @{binding order}
   450     (Scan.succeed (Toplevel.unknown_context o
   444       (Scan.lift ((Args.add -- Args.name >> (fn (_, s) => SOME s) || Args.del >> K NONE) --|
   451       Toplevel.keep (print_structures o Toplevel.context_of)));
   445         Args.colon (* FIXME || Scan.succeed true *) ) -- Scan.lift Args.name --
       
   446         Scan.repeat Args.term
       
   447         >> (fn ((SOME tag, n), ts) => add_struct_thm (n, ts) tag
       
   448              | ((NONE, n), ts) => del_struct (n, ts)))
       
   449       "theorems controlling transitivity reasoner");
   452 
   450 
   453 end;
   451 end;
   454 
       
   455 *}
   452 *}
   456 
       
   457 setup Orders.attrib_setup
       
   458 
   453 
   459 method_setup order = {*
   454 method_setup order = {*
   460   Scan.succeed (fn ctxt => SIMPLE_METHOD' (Orders.order_tac ctxt []))
   455   Scan.succeed (fn ctxt => SIMPLE_METHOD' (Orders.order_tac ctxt []))
   461 *} "transitivity reasoner"
   456 *} "transitivity reasoner"
   462 
   457