src/HOL/Tools/Function/lexicographic_order.ML
author wenzelm
Sat, 25 Jul 2009 10:31:27 +0200
changeset 32187 cca43ca13f4f
parent 32167 d32817dda0e6
child 32603 e08fdd615333
permissions -rw-r--r--
renamed structure Display_Goal to Goal_Display;
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
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
     9
  val lex_order_tac : Proof.context -> tactic -> tactic
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
    10
  val lexicographic_order_tac : Proof.context -> tactic
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
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    16
structure LexicographicOrder : LEXICOGRAPHIC_ORDER =
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    17
struct
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    18
27790
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    19
open FundefLib
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 =
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    24
    let 
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    25
        val relT = HOLogic.mk_setT (HOLogic.mk_prodT (domT, domT))
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    26
        val mlexT = (domT --> HOLogic.natT) --> relT --> relT
30304
d8e4cd2ac2a1 set operations Int, Un, INTER, UNION, Inter, Union, empty, UNIV are now proper qualified constants with authentic syntax
haftmann
parents: 29713
diff changeset
    27
        fun mk_ms [] = Const (@{const_name Set.empty}, relT)
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    28
          | mk_ms (f::fs) = 
26748
4d51ddd6aa5c Merged theories about wellfoundedness into one: Wellfounded.thy
krauss
parents: 26529
diff changeset
    29
            Const (@{const_name "mlex_prod"}, mlexT) $ f $ mk_ms fs
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    30
    in
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    31
        mk_ms mfuns
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    32
    end
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) =
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
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
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
    43
datatype cell = 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
    44
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    45
fun is_Less (Less _) = true
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    46
  | is_Less _ = false
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    47
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    48
fun is_LessEq (LessEq _) = true
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    49
  | is_LessEq _ = false
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    50
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    51
fun pr_cell (Less _ ) = " < "
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    52
  | pr_cell (LessEq _) = " <="
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    53
  | pr_cell (None _) = " ? "
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
    54
  | pr_cell (False _) = " F "
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    55
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    56
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    57
(** Proof attempts to build the matrix **)
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    58
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    59
fun dest_term (t : term) =
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    60
    let
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    61
      val (vars, prop) = FundefLib.dest_all_all t
26529
03ad378ed5f0 Function package no longer overwrites theorems.
krauss
parents: 25545
diff changeset
    62
      val (prems, concl) = Logic.strip_horn prop
03ad378ed5f0 Function package no longer overwrites theorems.
krauss
parents: 25545
diff changeset
    63
      val (lhs, rhs) = concl
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    64
                         |> HOLogic.dest_Trueprop
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    65
                         |> HOLogic.dest_mem |> fst
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    66
                         |> HOLogic.dest_prod
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    67
    in
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    68
      (vars, prems, lhs, rhs)
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    69
    end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    70
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    71
fun mk_goal (vars, prems, lhs, rhs) rel =
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    72
    let
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
    73
      val concl = HOLogic.mk_binrel rel (lhs, rhs) |> HOLogic.mk_Trueprop
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    74
    in
27330
1af2598b5f7d Logic.all/mk_equals/mk_implies;
wenzelm
parents: 26875
diff changeset
    75
      fold_rev Logic.all vars (Logic.list_implies (prems, concl))
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    76
    end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    77
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    78
fun prove thy solve_tac t =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    79
    cterm_of thy t |> Goal.init
23055
34158639dc12 Method "lexicographic_order" now takes the same arguments as "auto"
krauss
parents: 22997
diff changeset
    80
    |> SINGLE solve_tac |> the
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    81
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    82
fun mk_cell (thy : theory) solve_tac (vars, prems, lhs, rhs) mfun =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
    83
    let
27790
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    84
      val goals = cterm_of thy o mk_goal (vars, prems, mfun $ lhs, mfun $ rhs)
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    85
    in
27790
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    86
      case try_proof (goals @{const_name HOL.less}) solve_tac of
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    87
        Solved thm => Less thm
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    88
      | Stuck thm => 
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    89
        (case try_proof (goals @{const_name HOL.less_eq}) solve_tac of
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    90
           Solved thm2 => LessEq (thm2, thm)
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    91
         | Stuck thm2 => 
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    92
           if prems_of thm2 = [HOLogic.Trueprop $ HOLogic.false_const] then False thm2
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    93
           else None (thm2, thm)
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    94
         | _ => raise Match) (* FIXME *)
37b4e65d1dbf FundefLib.try_proof : attempt a proof and see if it works
krauss
parents: 27721
diff changeset
    95
      | _ => raise Match
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
    96
    end
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    97
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    98
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
    99
(** Search algorithms **)
22309
87ec1ca65312 improved lexicographic order termination tactic
bulwahn
parents: 22258
diff changeset
   100
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   101
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
   102
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   103
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
   104
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   105
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
   106
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   107
(* simple depth-first search algorithm for the table *)
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   108
fun search_table table =
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   109
    case table of
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   110
      [] => SOME []
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   111
    | _ =>
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   112
      let
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   113
        val col = find_index (check_col) (transpose table)
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   114
      in case col of
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   115
           ~1 => NONE
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   116
         | _ =>
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   117
           let
22309
87ec1ca65312 improved lexicographic order termination tactic
bulwahn
parents: 22258
diff changeset
   118
             val order_opt = (table, col) |-> transform_table |> search_table
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   119
           in case order_opt of
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   120
                NONE => NONE
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   121
              | SOME order =>SOME (col :: transform_order col order)
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   122
           end
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   123
      end
22258
0967b03844b5 changes in lexicographic_order termination tactic
bulwahn
parents: 21817
diff changeset
   124
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   125
(** Proof Reconstruction **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   126
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   127
(* prove row :: cell list -> tactic *)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   128
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
   129
    (rtac @{thm "mlex_less"} 1)
24977
9f98751c9628 replaced (flip Thm.implies_elim) by Thm.elim_implies;
wenzelm
parents: 24961
diff changeset
   130
    THEN PRIMITIVE (Thm.elim_implies less_thm)
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   131
  | 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
   132
    (rtac @{thm "mlex_leq"} 1)
24977
9f98751c9628 replaced (flip Thm.implies_elim) by Thm.elim_implies;
wenzelm
parents: 24961
diff changeset
   133
    THEN PRIMITIVE (Thm.elim_implies lesseq_thm)
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   134
    THEN prove_row tail
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   135
  | prove_row _ = sys_error "lexicographic_order"
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   136
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   137
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   138
(** Error reporting **)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   139
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   140
fun pr_table table = writeln (cat_lines (map (fn r => concat (map pr_cell r)) table))
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   141
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   142
fun pr_goals ctxt st =
32187
cca43ca13f4f renamed structure Display_Goal to Goal_Display;
wenzelm
parents: 32167
diff changeset
   143
    Goal_Display.pretty_goals ctxt {total = true, main = false, maxgoals = Thm.nprems_of st} st
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   144
     |> Pretty.chunks
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   145
     |> Pretty.string_of
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   146
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   147
fun row_index i = chr (i + 97)
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   148
fun col_index j = string_of_int (j + 1)
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   149
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   150
fun pr_unprovable_cell _ ((i,j), Less _) = ""
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   151
  | pr_unprovable_cell ctxt ((i,j), LessEq (_, st)) =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   152
      "(" ^ 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
   153
  | 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
   154
      "(" ^ 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
   155
      ^ "\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
   156
  | pr_unprovable_cell ctxt ((i,j), False st) =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   157
      "(" ^ row_index i ^ ", " ^ col_index j ^ ", <):\n" ^ pr_goals ctxt st
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   158
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   159
fun pr_unprovable_subgoals ctxt table =
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   160
    table
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   161
     |> map_index (fn (i,cs) => map_index (fn (j,x) => ((i,j), x)) cs)
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   162
     |> flat
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   163
     |> map (pr_unprovable_cell ctxt)
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   164
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   165
fun no_order_msg ctxt table tl measure_funs =
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   166
    let
24920
2a45e400fdad generic Syntax.pretty/string_of operations;
wenzelm
parents: 24576
diff changeset
   167
      val prterm = Syntax.string_of_term ctxt
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   168
      fun pr_fun t i = string_of_int i ^ ") " ^ prterm t
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   169
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   170
      fun pr_goal t i =
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   171
          let
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   172
            val (_, _, lhs, rhs) = dest_term t
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   173
          in (* also show prems? *)
23128
8e0abe0fa80f clarified error message
krauss
parents: 23074
diff changeset
   174
               i ^ ") " ^ prterm rhs ^ " ~> " ^ prterm lhs
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   175
          end
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   176
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   177
      val gc = map (fn i => chr (i + 96)) (1 upto length table)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   178
      val mc = 1 upto length measure_funs
30715
e23e15f52d42 avoid mixing of left/right associative infixes, to make it work with experimental Poly/ML 5.3 branch;
wenzelm
parents: 30541
diff changeset
   179
      val tstr = "Result matrix:" ::  ("   " ^ concat (map (enclose " " " " o string_of_int) mc))
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   180
                 :: map2 (fn r => fn i => i ^ ": " ^ concat (map pr_cell r)) table gc
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   181
      val gstr = "Calls:" :: map2 (prefix "  " oo pr_goal) tl gc
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   182
      val mstr = "Measures:" :: map2 (prefix "  " oo pr_fun) measure_funs mc
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   183
      val ustr = "Unfinished subgoals:" :: pr_unprovable_subgoals ctxt table
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   184
    in
23437
4a44fcc9dba9 tuned error msg
krauss
parents: 23128
diff changeset
   185
      cat_lines (ustr @ gstr @ mstr @ tstr @ ["", "Could not find lexicographic termination order."])
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   186
    end
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   187
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   188
(** The Main Function **)
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   189
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   190
fun lex_order_tac ctxt solve_tac (st: thm) =
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   191
    let
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   192
      val thy = ProofContext.theory_of ctxt
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   193
      val ((trueprop $ (wf $ rel)) :: tl) = prems_of st
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   194
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   195
      val (domT, _) = HOLogic.dest_prodT (HOLogic.dest_setT (fastype_of rel))
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   196
26875
e18574413bc4 Measure functions can now be declared via special rules, allowing for a
krauss
parents: 26749
diff changeset
   197
      val measure_funs = MeasureFunctions.get_measure_functions ctxt domT (* 1: generate measures *)
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   198
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   199
      (* 2: create table *)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   200
      val table = map (fn t => map (mk_cell thy solve_tac (dest_term t)) measure_funs) tl
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   201
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   202
      val order = the (search_table table) (* 3: search table *)
23633
f25b1566f7b5 pr_goals: adapted Display.pretty_goals_aux;
wenzelm
parents: 23437
diff changeset
   203
          handle Option => error (no_order_msg ctxt table tl measure_funs)
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   204
21237
b803f9870e97 untabified
krauss
parents: 21201
diff changeset
   205
      val clean_table = map (fn x => map (nth x) order) table
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   206
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   207
      val relation = mk_measures domT (map (nth measure_funs) order)
24920
2a45e400fdad generic Syntax.pretty/string_of operations;
wenzelm
parents: 24576
diff changeset
   208
      val _ = writeln ("Found termination order: " ^ quote (Syntax.string_of_term ctxt relation))
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   209
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   210
    in (* 4: proof reconstruction *)
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   211
      st |> (PRIMITIVE (cterm_instantiate [(cterm_of thy rel, cterm_of thy relation)])
24576
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
   212
              THEN (REPEAT (rtac @{thm "wf_mlex"} 1))
32ddd902b0ad lexicographic_order method uses "<*mlex*>" instead of "measures" => no longer depends on List.thy
krauss
parents: 23881
diff changeset
   213
              THEN (rtac @{thm "wf_empty"} 1)
23074
a53cb8ddb052 some optimizations, cleanup
krauss
parents: 23056
diff changeset
   214
              THEN EVERY (map prove_row clean_table))
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   215
    end
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   216
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   217
fun lexicographic_order_tac ctxt =
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   218
  TRY (FundefCommon.apply_termination_rule ctxt 1)
31902
862ae16a799d renamed NamedThmsFun to Named_Thms;
wenzelm
parents: 31775
diff changeset
   219
  THEN lex_order_tac ctxt
32149
ef59550a55d3 renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
wenzelm
parents: 32145
diff changeset
   220
    (auto_tac (clasimpset_of ctxt addsimps2 FundefCommon.Termination_Simps.get ctxt))
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   221
30510
4120fc59dd85 unified type Proof.method and pervasive METHOD combinators;
wenzelm
parents: 30493
diff changeset
   222
val lexicographic_order = SIMPLE_METHOD o lexicographic_order_tac
21201
803bc7672d17 method exported
krauss
parents: 21131
diff changeset
   223
30541
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   224
val setup =
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   225
  Method.setup @{binding lexicographic_order}
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   226
    (Method.sections clasimp_modifiers >> (K lexicographic_order))
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   227
    "termination prover for lexicographic orderings"
9f168bdc468a simplified method setup;
wenzelm
parents: 30510
diff changeset
   228
  #> Context.theory_map (FundefCommon.set_termination_prover lexicographic_order)
21131
a447addc14af added lexicographic_order tactic
bulwahn
parents:
diff changeset
   229
30493
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   230
end;
b8570ea1ce25 provide regular ML interfaces for Isar source language elements;
wenzelm
parents: 30304
diff changeset
   231