src/HOL/Tools/Function/lexicographic_order.ML
author wenzelm
Fri, 03 Sep 2010 21:13:53 +0200
changeset 39125 f45d332a90e3
parent 36521 73ed9f18fdd3
child 39926 4b3b384d3de3
permissions -rw-r--r--
pretty_goals: turned some global references and function arguments into configuration options (goals_limit = 10, goals_total = true, show_main_goal = false) depending on the context;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
31775
2b04504fcb69 uniformly capitialized names for subdirectories
haftmann
parents: 30715
diff changeset
     1
(*  Title:       HOL/Tools/Function/lexicographic_order.ML
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     2
    Author:      Lukas Bulwahn, TU Muenchen
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     3
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     4
Method for termination proofs with lexicographic orderings.
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     5
*)
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     6
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     7
signature LEXICOGRAPHIC_ORDER =
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
     8
sig
33351
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
     9
  val lex_order_tac : bool -> Proof.context -> tactic -> tactic
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
    10
  val lexicographic_order_tac : bool -> Proof.context -> tactic
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
    11
  val lexicographic_order : Proof.context -> Proof.method
21510
7e72185e4b24 exported mk_base_funs for use by size-change tools
krauss
parents: 21319
diff changeset
    12
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
    13
  val setup: theory -> theory
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    14
end
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    15
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 32952
diff changeset
    16
structure Lexicographic_Order : LEXICOGRAPHIC_ORDER =
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    17
struct
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    18
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 32952
diff changeset
    19
open Function_Lib
27790
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    20
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    21
(** General stuff **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    22
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    23
fun mk_measures domT mfuns =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    24
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    25
    val relT = HOLogic.mk_setT (HOLogic.mk_prodT (domT, domT))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    26
    val mlexT = (domT --> HOLogic.natT) --> relT --> relT
35402
115a5a95710a clarified @{const_name} vs. @{const_abbrev};
wenzelm
parents: 35092
diff changeset
    27
    fun mk_ms [] = Const (@{const_abbrev Set.empty}, relT)
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    28
      | mk_ms (f::fs) =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    29
        Const (@{const_name mlex_prod}, mlexT) $ f $ mk_ms fs
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    30
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    31
    mk_ms mfuns
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    32
  end
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    33
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    34
fun del_index n [] = []
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    35
  | del_index n (x :: xs) =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    36
  if n > 0 then x :: del_index (n - 1) xs else xs
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    37
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    38
fun transpose ([]::_) = []
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    39
  | transpose xss = map hd xss :: transpose (map tl xss)
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    40
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    41
(** Matrix cell datatype **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    42
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    43
datatype cell =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    44
  Less of thm| LessEq of (thm * thm) | None of (thm * thm) | False of thm;
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    45
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    46
fun is_Less (Less _) = true
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    47
  | is_Less _ = false
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    48
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    49
fun is_LessEq (LessEq _) = true
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    50
  | is_LessEq _ = false
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    51
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    52
fun pr_cell (Less _ ) = " < "
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    53
  | pr_cell (LessEq _) = " <="
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    54
  | pr_cell (None _) = " ? "
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    55
  | pr_cell (False _) = " F "
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    56
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    57
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    58
(** Proof attempts to build the matrix **)
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    59
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    60
fun dest_term (t : term) =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    61
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    62
    val (vars, prop) = Function_Lib.dest_all_all t
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    63
    val (prems, concl) = Logic.strip_horn prop
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    64
    val (lhs, rhs) = concl
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    65
      |> HOLogic.dest_Trueprop
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    66
      |> HOLogic.dest_mem |> fst
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    67
      |> HOLogic.dest_prod
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    68
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    69
    (vars, prems, lhs, rhs)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    70
  end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    71
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    72
fun mk_goal (vars, prems, lhs, rhs) rel =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    73
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    74
    val concl = HOLogic.mk_binrel rel (lhs, rhs) |> HOLogic.mk_Trueprop
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    75
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    76
    fold_rev Logic.all vars (Logic.list_implies (prems, concl))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    77
  end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    78
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    79
fun mk_cell (thy : theory) solve_tac (vars, prems, lhs, rhs) mfun =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    80
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    81
    val goals = cterm_of thy o mk_goal (vars, prems, mfun $ lhs, mfun $ rhs)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    82
  in
35092
cfe605c54e50 moved less_eq, less to Orderings.thy; moved abs, sgn to Groups.thy
haftmann
parents: 34974
diff changeset
    83
    case try_proof (goals @{const_name Orderings.less}) solve_tac of
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    84
      Solved thm => Less thm
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    85
    | Stuck thm =>
35092
cfe605c54e50 moved less_eq, less to Orderings.thy; moved abs, sgn to Groups.thy
haftmann
parents: 34974
diff changeset
    86
      (case try_proof (goals @{const_name Orderings.less_eq}) solve_tac of
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    87
         Solved thm2 => LessEq (thm2, thm)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    88
       | Stuck thm2 =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    89
         if prems_of thm2 = [HOLogic.Trueprop $ HOLogic.false_const] then False thm2
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    90
         else None (thm2, thm)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    91
       | _ => raise Match) (* FIXME *)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    92
    | _ => raise Match
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
    93
  end
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    94
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    95
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    96
(** Search algorithms **)
22309
87ec1ca65312 improved lexicographic order termination tactic
bulwahn
parents: 22258
diff changeset
    97
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    98
fun check_col ls = forall (fn c => is_Less c orelse is_LessEq c) ls andalso not (forall (is_LessEq) ls)
22309
87ec1ca65312 improved lexicographic order termination tactic
bulwahn
parents: 22258
diff changeset
    99
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   100
fun transform_table table col = table |> filter_out (fn x => is_Less (nth x col)) |> map (del_index col)
22309
87ec1ca65312 improved lexicographic order termination tactic
bulwahn
parents: 22258
diff changeset
   101
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   102
fun transform_order col order = map (fn x => if x >= col then x + 1 else x) order
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   103
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   104
(* simple depth-first search algorithm for the table *)
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   105
fun search_table table =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   106
  case table of
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   107
    [] => SOME []
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   108
  | _ =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   109
    let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   110
      val col = find_index (check_col) (transpose table)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   111
    in case col of
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   112
         ~1 => NONE
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   113
       | _ =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   114
         let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   115
           val order_opt = (table, col) |-> transform_table |> search_table
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   116
         in case order_opt of
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   117
              NONE => NONE
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   118
            | SOME order =>SOME (col :: transform_order col order)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   119
         end
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   120
    end
22258
0967b03844b5 changes in lexicographic_order termination tactic
bulwahn
parents: 21817
diff changeset
   121
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   122
(** Proof Reconstruction **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   123
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   124
(* prove row :: cell list -> tactic *)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   125
fun prove_row (Less less_thm :: _) =
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
   126
    (rtac @{thm "mlex_less"} 1)
24977
9f98751c9628 replaced (flip Thm.implies_elim) by Thm.elim_implies;
wenzelm
parents: 24961
diff changeset
   127
    THEN PRIMITIVE (Thm.elim_implies less_thm)
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   128
  | prove_row (LessEq (lesseq_thm, _) :: tail) =
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
   129
    (rtac @{thm "mlex_leq"} 1)
24977
9f98751c9628 replaced (flip Thm.implies_elim) by Thm.elim_implies;
wenzelm
parents: 24961
diff changeset
   130
    THEN PRIMITIVE (Thm.elim_implies lesseq_thm)
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   131
    THEN prove_row tail
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   132
  | prove_row _ = sys_error "lexicographic_order"
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   133
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   134
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   135
(** Error reporting **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   136
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   137
fun pr_goals ctxt st =
39125
f45d332a90e3 pretty_goals: turned some global references and function arguments into configuration options (goals_limit = 10, goals_total = true, show_main_goal = false) depending on the context;
wenzelm
parents: 36521
diff changeset
   138
  Goal_Display.pretty_goals
f45d332a90e3 pretty_goals: turned some global references and function arguments into configuration options (goals_limit = 10, goals_total = true, show_main_goal = false) depending on the context;
wenzelm
parents: 36521
diff changeset
   139
    (Config.put Goal_Display.goals_limit (Thm.nprems_of st) ctxt) st
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   140
  |> Pretty.chunks
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   141
  |> Pretty.string_of
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   142
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   143
fun row_index i = chr (i + 97)
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   144
fun col_index j = string_of_int (j + 1)
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   145
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   146
fun pr_unprovable_cell _ ((i,j), Less _) = ""
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   147
  | pr_unprovable_cell ctxt ((i,j), LessEq (_, st)) =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   148
      "(" ^ row_index i ^ ", " ^ col_index j ^ ", <):\n" ^ pr_goals ctxt st
26875
e18574413bc4 Measure functions can now be declared via special rules, allowing for a
krauss
parents: 26749
diff changeset
   149
  | pr_unprovable_cell ctxt ((i,j), None (st_leq, st_less)) =
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   150
      "(" ^ row_index i ^ ", " ^ col_index j ^ ", <):\n" ^ pr_goals ctxt st_less
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   151
      ^ "\n(" ^ row_index i ^ ", " ^ col_index j ^ ", <=):\n" ^ pr_goals ctxt st_leq
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   152
  | pr_unprovable_cell ctxt ((i,j), False st) =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   153
      "(" ^ row_index i ^ ", " ^ col_index j ^ ", <):\n" ^ pr_goals ctxt st
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   154
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   155
fun pr_unprovable_subgoals ctxt table =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   156
  table
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   157
  |> map_index (fn (i,cs) => map_index (fn (j,x) => ((i,j), x)) cs)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   158
  |> flat
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   159
  |> map (pr_unprovable_cell ctxt)
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   160
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   161
fun no_order_msg ctxt table tl measure_funs =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   162
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   163
    val prterm = Syntax.string_of_term ctxt
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   164
    fun pr_fun t i = string_of_int i ^ ") " ^ prterm t
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   165
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   166
    fun pr_goal t i =
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   167
      let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   168
        val (_, _, lhs, rhs) = dest_term t
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   169
      in (* also show prems? *)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   170
           i ^ ") " ^ prterm rhs ^ " ~> " ^ prterm lhs
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   171
      end
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   172
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   173
    val gc = map (fn i => chr (i + 96)) (1 upto length table)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   174
    val mc = 1 upto length measure_funs
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   175
    val tstr = "Result matrix:" ::  ("   " ^ implode (map (enclose " " " " o string_of_int) mc))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   176
      :: map2 (fn r => fn i => i ^ ": " ^ implode (map pr_cell r)) table gc
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   177
    val gstr = "Calls:" :: map2 (prefix "  " oo pr_goal) tl gc
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   178
    val mstr = "Measures:" :: map2 (prefix "  " oo pr_fun) measure_funs mc
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   179
    val ustr = "Unfinished subgoals:" :: pr_unprovable_subgoals ctxt table
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   180
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   181
    cat_lines (ustr @ gstr @ mstr @ tstr @
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   182
    ["", "Could not find lexicographic termination order."])
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   183
  end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   184
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   185
(** The Main Function **)
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   186
33351
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
   187
fun lex_order_tac quiet ctxt solve_tac (st: thm) =
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   188
  let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   189
    val thy = ProofContext.theory_of ctxt
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   190
    val ((_ $ (_ $ rel)) :: tl) = prems_of st
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   191
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   192
    val (domT, _) = HOLogic.dest_prodT (HOLogic.dest_setT (fastype_of rel))
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   193
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   194
    val measure_funs = (* 1: generate measures *)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   195
      MeasureFunctions.get_measure_functions ctxt domT
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   196
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   197
    val table = (* 2: create table *)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   198
      Par_List.map (fn t => Par_List.map (mk_cell thy solve_tac (dest_term t)) measure_funs) tl
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   199
  in
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   200
    case search_table table of
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   201
      NONE => if quiet then no_tac st else error (no_order_msg ctxt table tl measure_funs)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   202
    | SOME order =>
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   203
      let
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   204
        val clean_table = map (fn x => map (nth x) order) table
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   205
        val relation = mk_measures domT (map (nth measure_funs) order)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   206
        val _ = if not quiet
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   207
          then writeln ("Found termination order: " ^ quote (Syntax.string_of_term ctxt relation))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   208
          else ()
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   209
34232
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   210
      in (* 4: proof reconstruction *)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   211
        st |> (PRIMITIVE (cterm_instantiate [(cterm_of thy rel, cterm_of thy relation)])
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   212
        THEN (REPEAT (rtac @{thm "wf_mlex"} 1))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   213
        THEN (rtac @{thm "wf_empty"} 1)
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   214
        THEN EVERY (map prove_row clean_table))
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   215
      end
36a2a3029fd3 new year's resolution: reindented code in function package
krauss
parents: 33855
diff changeset
   216
  end
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   217
33351
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
   218
fun lexicographic_order_tac quiet ctxt =
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 32952
diff changeset
   219
  TRY (Function_Common.apply_termination_rule ctxt 1)
33351
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
   220
  THEN lex_order_tac quiet ctxt
33099
b8cdd3d73022 function package: more standard names for structures and files
krauss
parents: 32952
diff changeset
   221
    (auto_tac (clasimpset_of ctxt addsimps2 Function_Common.Termination_Simps.get ctxt))
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   222
33351
37ec56ac3fd4 less verbose termination tactics
krauss
parents: 33099
diff changeset
   223
val lexicographic_order = SIMPLE_METHOD o lexicographic_order_tac false
21201
803bc7672d17 method exported
krauss
parents: 21131
diff changeset
   224
30541
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   225
val setup =
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   226
  Method.setup @{binding lexicographic_order}
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   227
    (Method.sections clasimp_modifiers >> (K lexicographic_order))
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   228
    "termination prover for lexicographic orderings"
36521
73ed9f18fdd3 default termination prover as plain tactic
krauss
parents: 35402
diff changeset
   229
  #> Context.theory_map (Function_Common.set_termination_prover (lexicographic_order_tac false))
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   230
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   231
end;