src/HOL/Statespace/distinct_tree_prover.ML
author wenzelm
Wed, 25 Aug 2010 18:36:22 +0200
changeset 38715 6513ea67d95d
parent 38558 32ad17fe2b9c
child 38864 4abe644fcea5
permissions -rw-r--r--
renamed Simplifier.simproc(_i) to Simplifier.simproc_global(_i) to emphasize that this is not the real thing;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29269
5c25a2012975 moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
wenzelm
parents: 29064
diff changeset
     1
(*  Title:      HOL/Statespace/distinct_tree_prover.ML
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
     2
    Author:     Norbert Schirmer, TU Muenchen
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
     3
*)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
     4
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
     5
signature DISTINCT_TREE_PROVER =
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
     6
sig
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
     7
  datatype Direction = Left | Right
29302
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
     8
  val mk_tree : ('a -> term) -> typ -> 'a list -> term
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
     9
  val dest_tree : term -> term list
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    10
  val find_tree : term -> term -> Direction list option 
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    11
29302
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    12
  val neq_to_eq_False : thm
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    13
  val distinctTreeProver : thm -> Direction list -> Direction list -> thm
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    14
  val neq_x_y : Proof.context -> term -> term -> string -> thm option   
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    15
  val distinctFieldSolver : string list -> solver
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    16
  val distinctTree_tac : string list -> Proof.context -> term * int -> tactic
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    17
  val distinct_implProver : thm -> cterm -> thm
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    18
  val subtractProver : term -> cterm -> thm -> thm
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    19
  val distinct_simproc : string list -> simproc
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    20
  
29302
eb782d1dc07c normalized some ML type/val aliases;
wenzelm
parents: 29269
diff changeset
    21
  val discharge : thm list -> thm -> thm
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    22
end;
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    23
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    24
structure DistinctTreeProver : DISTINCT_TREE_PROVER =
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    25
struct
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    26
val all_distinct_left = thm "DistinctTreeProver.all_distinct_left";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    27
val all_distinct_right = thm "DistinctTreeProver.all_distinct_right";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    28
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    29
val distinct_left = thm "DistinctTreeProver.distinct_left";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    30
val distinct_right = thm "DistinctTreeProver.distinct_right";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    31
val distinct_left_right = thm "DistinctTreeProver.distinct_left_right";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    32
val in_set_root = thm "DistinctTreeProver.in_set_root";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    33
val in_set_left = thm "DistinctTreeProver.in_set_left";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    34
val in_set_right = thm "DistinctTreeProver.in_set_right";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    35
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    36
val swap_neq = thm "DistinctTreeProver.swap_neq";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    37
val neq_to_eq_False = thm "DistinctTreeProver.neq_to_eq_False"
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    38
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    39
datatype Direction = Left | Right 
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    40
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    41
fun treeT T = Type ("DistinctTreeProver.tree",[T]);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    42
fun mk_tree' e T n []     = Const ("DistinctTreeProver.tree.Tip",treeT T)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    43
  | mk_tree' e T n xs =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    44
     let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    45
       val m = (n - 1) div 2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    46
       val (xsl,x::xsr) = chop m xs;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    47
       val l = mk_tree' e T m xsl;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    48
       val r = mk_tree' e T (n-(m+1)) xsr;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    49
     in Const ("DistinctTreeProver.tree.Node",
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    50
                treeT T --> T --> HOLogic.boolT--> treeT T --> treeT T) $ 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    51
          l$ e x $ HOLogic.false_const $ r 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    52
     end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    53
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    54
fun mk_tree e T xs = mk_tree' e T (length xs) xs;         
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    55
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    56
fun dest_tree (Const ("DistinctTreeProver.tree.Tip",_)) = []
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    57
  | dest_tree (Const ("DistinctTreeProver.tree.Node",_)$l$e$_$r) = dest_tree l @ e :: dest_tree r
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    58
  | dest_tree t = raise TERM ("DistinctTreeProver.dest_tree",[t]);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    59
25408
156f6f7082b8 added signatures;
schirmer
parents: 25171
diff changeset
    60
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    61
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    62
fun lin_find_tree e (Const ("DistinctTreeProver.tree.Tip",_)) = NONE
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    63
  | lin_find_tree e (Const ("DistinctTreeProver.tree.Node",_) $ l$ x $ _ $ r) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    64
      if e aconv x 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    65
      then SOME []
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    66
      else (case lin_find_tree e l of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    67
              SOME path => SOME (Left::path)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    68
            | NONE => (case lin_find_tree e r of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    69
                        SOME path => SOME (Right::path)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    70
                       | NONE => NONE))
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    71
  | lin_find_tree e t = raise TERM ("find_tree: input not a tree",[t])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    72
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    73
fun bin_find_tree order e (Const ("DistinctTreeProver.tree.Tip",_)) = NONE
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    74
  | bin_find_tree order e (Const ("DistinctTreeProver.tree.Node",_) $ l$ x $ _ $ r) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    75
      (case order (e,x) of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    76
         EQUAL => SOME []
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    77
       | LESS => Option.map (cons Left) (bin_find_tree order e l)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    78
       | GREATER => Option.map (cons Right) (bin_find_tree order e r))
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    79
  | bin_find_tree order e t = raise TERM ("find_tree: input not a tree",[t])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    80
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    81
fun find_tree e t =
35408
b48ab741683b modernized structure Term_Ord;
wenzelm
parents: 30289
diff changeset
    82
  (case bin_find_tree Term_Ord.fast_term_ord e t of
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    83
     NONE => lin_find_tree e t
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    84
   | x => x);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    85
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    86
 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    87
fun index_tree (Const ("DistinctTreeProver.tree.Tip",_)) path tab = tab
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    88
  | index_tree (Const ("DistinctTreeProver.tree.Node",_) $ l$ x $ _ $ r) path tab =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    89
      tab 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    90
      |> Termtab.update_new (x,path) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    91
      |> index_tree l (path@[Left])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    92
      |> index_tree r (path@[Right])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    93
  | index_tree t _ _ = raise TERM ("index_tree: input not a tree",[t])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    94
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    95
fun split_common_prefix xs [] = ([],xs,[])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    96
  | split_common_prefix [] ys = ([],[],ys)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    97
  | split_common_prefix (xs as (x::xs')) (ys as (y::ys')) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    98
     if x=y 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
    99
     then let val (ps,xs'',ys'') = split_common_prefix xs' ys' in (x::ps,xs'',ys'') end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   100
     else ([],xs,ys)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   101
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   102
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   103
(* Wrapper around Thm.instantiate. The type instiations of instTs are applied to
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   104
 * the right hand sides of insts
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   105
 *)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   106
fun instantiate instTs insts =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   107
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   108
    val instTs' = map (fn (T,U) => (dest_TVar (typ_of T),typ_of U)) instTs;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   109
    fun substT x = (case AList.lookup (op =) instTs' x of NONE => TVar x | SOME T' => T');
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   110
    fun mapT_and_recertify ct =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   111
      let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   112
        val thy = theory_of_cterm ct;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   113
      in (cterm_of thy (Term.map_types (Term.map_type_tvar substT) (term_of ct))) end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   114
    val insts' = map (apfst mapT_and_recertify) insts;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   115
  in Thm.instantiate (instTs,insts') end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   116
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   117
fun tvar_clash ixn S S' = raise TYPE ("Type variable " ^
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   118
  quote (Term.string_of_vname ixn) ^ " has two distinct sorts",
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   119
  [TVar (ixn, S), TVar (ixn, S')], []);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   120
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   121
fun lookup (tye, (ixn, S)) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   122
  (case AList.lookup (op =) tye ixn of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   123
    NONE => NONE
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   124
  | SOME (S', T) => if S = S' then SOME T else tvar_clash ixn S S');
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   125
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   126
val naive_typ_match =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   127
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   128
    fun match (TVar (v, S), T) subs =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   129
          (case lookup (subs, (v, S)) of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   130
            NONE => ((v, (S, T))::subs)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   131
          | SOME _ => subs)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   132
      | match (Type (a, Ts), Type (b, Us)) subs =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   133
          if a <> b then raise Type.TYPE_MATCH
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   134
          else matches (Ts, Us) subs
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   135
      | match (TFree x, TFree y) subs =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   136
          if x = y then subs else raise Type.TYPE_MATCH
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   137
      | match _ _ = raise Type.TYPE_MATCH
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   138
    and matches (T :: Ts, U :: Us) subs = matches (Ts, Us) (match (T, U) subs)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   139
      | matches _ subs = subs;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   140
  in match end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   141
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   142
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   143
(* expects that relevant type variables are already contained in 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   144
 * term variables. First instantiation of variables is returned without further
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   145
 * checking.
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   146
 *)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   147
fun naive_cterm_first_order_match (t,ct) env =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   148
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   149
    val thy = (theory_of_cterm ct);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   150
    fun mtch (env as (tyinsts,insts)) = fn
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   151
         (Var(ixn,T),ct) =>
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   152
           (case AList.lookup (op =) insts ixn of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   153
             NONE => (naive_typ_match (T,typ_of (ctyp_of_term ct)) tyinsts,
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   154
                      (ixn, ct)::insts)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   155
            | SOME _ => env)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   156
        | (f$t,ct) => let val (cf,ct') = Thm.dest_comb ct;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   157
                      in mtch (mtch env (f,cf)) (t,ct') end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   158
        | _ => env
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   159
  in mtch env (t,ct) end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   160
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   161
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   162
fun discharge prems rule =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   163
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   164
     val thy = theory_of_thm (hd prems);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   165
     val (tyinsts,insts) =  
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   166
           fold naive_cterm_first_order_match (prems_of rule ~~ map cprop_of prems) ([],[]);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   167
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   168
     val tyinsts' = map (fn (v,(S,U)) => (ctyp_of thy (TVar (v,S)),ctyp_of thy U)) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   169
                     tyinsts;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   170
     val insts' = map (fn (idxn,ct) => (cterm_of thy (Var (idxn,typ_of (ctyp_of_term ct))),ct))  
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   171
                     insts;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   172
     val rule' = Thm.instantiate (tyinsts',insts') rule;
36943
wenzelm
parents: 35408
diff changeset
   173
   in fold Thm.elim_implies prems rule' end;
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   174
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   175
local
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   176
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   177
val (l_in_set_root,x_in_set_root,r_in_set_root) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   178
  let val (Node_l_x_d,r) = (cprop_of in_set_root) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   179
                         |> Thm.dest_comb |> #2 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   180
                         |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   181
      val (Node_l,x) = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   182
      val l = Node_l |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   183
  in (l,x,r) end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   184
val (x_in_set_left,r_in_set_left) = 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   185
  let val (Node_l_x_d,r) = (cprop_of in_set_left) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   186
                         |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   187
                         |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 |> Thm.dest_comb;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   188
      val x = Node_l_x_d |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   189
  in (x,r) end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   190
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   191
val (x_in_set_right,l_in_set_right) = 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   192
  let val (Node_l,x) = (cprop_of in_set_right) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   193
                         |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   194
                         |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   195
                         |> Thm.dest_comb |> #1 |> Thm.dest_comb |> #1 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   196
                         |> Thm.dest_comb
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   197
      val l = Node_l |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   198
  in (x,l) end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   199
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   200
in
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   201
(*
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   202
1. First get paths x_path y_path of x and y in the tree.
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   203
2. For the common prefix descend into the tree according to the path
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   204
   and lemmas all_distinct_left/right
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   205
3. If one restpath is empty use distinct_left/right,
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   206
   otherwise all_distinct_left_right
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   207
*)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   208
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   209
fun distinctTreeProver dist_thm x_path y_path =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   210
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   211
    fun dist_subtree [] thm = thm
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   212
      | dist_subtree (p::ps) thm =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   213
         let 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   214
           val rule = (case p of Left => all_distinct_left | Right => all_distinct_right)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   215
         in dist_subtree ps (discharge [thm] rule) end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   216
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   217
    val (ps,x_rest,y_rest) = split_common_prefix x_path y_path;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   218
    val dist_subtree_thm = dist_subtree ps dist_thm;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   219
    val subtree = cprop_of dist_subtree_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   220
    val (_,[l,_,_,r]) = Drule.strip_comb subtree;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   221
    
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   222
    fun in_set ps tree =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   223
      let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   224
        val (_,[l,x,_,r]) = Drule.strip_comb tree;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   225
        val xT = ctyp_of_term x;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   226
      in (case ps of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   227
            [] => instantiate 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   228
                    [(ctyp_of_term x_in_set_root,xT)]
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   229
                    [(l_in_set_root,l),(x_in_set_root,x),(r_in_set_root,r)] in_set_root
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   230
          | (Left::ps') => 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   231
               let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   232
                  val in_set_l = in_set ps' l;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   233
                  val in_set_left' = instantiate [(ctyp_of_term x_in_set_left,xT)]
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   234
                                      [(x_in_set_left,x),(r_in_set_left,r)] in_set_left;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   235
               in discharge [in_set_l] in_set_left' end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   236
          | (Right::ps') => 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   237
               let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   238
                  val in_set_r = in_set ps' r;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   239
                  val in_set_right' = instantiate [(ctyp_of_term x_in_set_right,xT)] 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   240
                                      [(x_in_set_right,x),(l_in_set_right,l)] in_set_right;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   241
               in discharge [in_set_r] in_set_right' end)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   242
      end 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   243
       
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   244
  fun in_set' [] = raise TERM ("distinctTreeProver",[])
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   245
    | in_set' (Left::ps) = in_set ps l
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   246
    | in_set' (Right::ps) = in_set ps r;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   247
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   248
  fun distinct_lr node_in_set Left  = discharge [dist_subtree_thm,node_in_set] distinct_left 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   249
    | distinct_lr node_in_set Right = discharge [dist_subtree_thm,node_in_set] distinct_right 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   250
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   251
  val (swap,neq) = 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   252
       (case x_rest of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   253
         [] => let 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   254
                 val y_in_set = in_set' y_rest;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   255
               in (false,distinct_lr y_in_set (hd y_rest)) end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   256
       | (xr::xrs) => 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   257
           (case y_rest of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   258
             [] => let 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   259
                     val x_in_set = in_set' x_rest;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   260
               in (true,distinct_lr x_in_set (hd x_rest)) end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   261
           | (yr::yrs) =>
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   262
               let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   263
                 val x_in_set = in_set' x_rest;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   264
                 val y_in_set = in_set' y_rest;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   265
               in (case xr of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   266
                    Left => (false,
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   267
                             discharge [dist_subtree_thm,x_in_set,y_in_set] distinct_left_right)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   268
                   |Right => (true,
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   269
                             discharge [dist_subtree_thm,y_in_set,x_in_set] distinct_left_right))
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   270
               end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   271
        ))
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   272
  in if swap then discharge [neq] swap_neq else neq
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   273
  end  
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   274
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   275
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   276
val delete_root = thm "DistinctTreeProver.delete_root";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   277
val delete_left = thm "DistinctTreeProver.delete_left";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   278
val delete_right = thm "DistinctTreeProver.delete_right";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   279
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   280
fun deleteProver dist_thm [] = delete_root OF [dist_thm]
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   281
  | deleteProver dist_thm (p::ps) =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   282
     let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   283
       val dist_rule = (case p of Left => all_distinct_left | Right => all_distinct_right);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   284
       val dist_thm' = discharge [dist_thm] dist_rule 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   285
       val del_rule = (case p of Left => delete_left | Right => delete_right)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   286
       val del = deleteProver dist_thm' ps;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   287
     in discharge [dist_thm, del] del_rule end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   288
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   289
val subtract_Tip = thm "DistinctTreeProver.subtract_Tip";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   290
val subtract_Node = thm "DistinctTreeProver.subtract_Node";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   291
val delete_Some_all_distinct = thm "DistinctTreeProver.delete_Some_all_distinct";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   292
val subtract_Some_all_distinct_res = thm "DistinctTreeProver.subtract_Some_all_distinct_res";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   293
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   294
local
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   295
  val (alpha,v) = 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   296
    let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   297
      val ct = subtract_Tip |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   298
               |> Thm.dest_comb |> #2
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   299
      val [alpha] = ct |> Thm.ctyp_of_term |> Thm.dest_ctyp;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   300
    in (alpha, #1 (dest_Var (term_of ct))) end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   301
in
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   302
fun subtractProver (Const ("DistinctTreeProver.tree.Tip",T)) ct dist_thm =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   303
    let 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   304
      val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   305
      val thy = theory_of_cterm ct;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   306
      val [alphaI] = #2 (dest_Type T);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   307
    in Thm.instantiate ([(alpha,ctyp_of thy alphaI)],
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   308
                        [(cterm_of thy (Var (v,treeT alphaI)),ct')]) subtract_Tip
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   309
    end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   310
  | subtractProver (Const ("DistinctTreeProver.tree.Node",nT)$l$x$d$r) ct dist_thm =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   311
    let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   312
      val ct' = dist_thm |> Thm.cprop_of |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   313
      val (_,[cl,_,_,cr]) = Drule.strip_comb ct;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   314
      val ps = the (find_tree x (term_of ct'));
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   315
      val del_tree = deleteProver dist_thm ps;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   316
      val dist_thm' = discharge [del_tree, dist_thm] delete_Some_all_distinct; 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   317
      val sub_l = subtractProver (term_of cl) cl (dist_thm');
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   318
      val sub_r = subtractProver (term_of cr) cr 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   319
                    (discharge [sub_l, dist_thm'] subtract_Some_all_distinct_res);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   320
    in discharge [del_tree, sub_l, sub_r] subtract_Node end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   321
end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   322
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   323
val subtract_Some_all_distinct = thm "DistinctTreeProver.subtract_Some_all_distinct";
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   324
fun distinct_implProver dist_thm ct =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   325
  let
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   326
    val ctree = ct |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   327
    val sub = subtractProver (term_of ctree) ctree dist_thm;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   328
  in subtract_Some_all_distinct OF [sub, dist_thm] end;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   329
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   330
fun get_fst_success f [] = NONE
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   331
  | get_fst_success f (x::xs) = (case f x of NONE => get_fst_success f xs 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   332
                                 | SOME v => SOME v);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   333
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   334
fun neq_x_y ctxt x y name =
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   335
  (let
26343
0dd2eab7b296 simplified get_thm(s): back to plain name argument;
wenzelm
parents: 26336
diff changeset
   336
    val dist_thm = the (try (ProofContext.get_thm ctxt) name);
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   337
    val ctree = cprop_of dist_thm |> Thm.dest_comb |> #2 |> Thm.dest_comb |> #2;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   338
    val tree = term_of ctree;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   339
    val x_path = the (find_tree x tree);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   340
    val y_path = the (find_tree y tree);
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   341
    val thm = distinctTreeProver dist_thm x_path y_path;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   342
  in SOME thm  
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   343
  end handle Option => NONE)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   344
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   345
fun distinctTree_tac names ctxt 
38558
32ad17fe2b9c tuned quotes
haftmann
parents: 38549
diff changeset
   346
      (Const (@{const_name Trueprop},_) $ (Const (@{const_name Not}, _) $ (Const (@{const_name "op ="}, _) $ x $ y)), i) =
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   347
  (case get_fst_success (neq_x_y ctxt x y) names of
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   348
     SOME neq => rtac neq i
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   349
   | NONE => no_tac)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   350
  | distinctTree_tac _ _ _ = no_tac;
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   351
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   352
fun distinctFieldSolver names = mk_solver' "distinctFieldSolver"
30289
b28caca9157f removed spurious occurrences of old rep_ss;
wenzelm
parents: 29302
diff changeset
   353
     (fn ss => case try Simplifier.the_context ss of
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   354
                 SOME ctxt => SUBGOAL (distinctTree_tac names ctxt)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   355
                | NONE => fn i => no_tac)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   356
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   357
fun distinct_simproc names =
38715
6513ea67d95d renamed Simplifier.simproc(_i) to Simplifier.simproc_global(_i) to emphasize that this is not the real thing;
wenzelm
parents: 38558
diff changeset
   358
  Simplifier.simproc_global @{theory HOL} "DistinctTreeProver.distinct_simproc" ["x = y"]
38549
d0385f2764d8 use antiquotations for remaining unqualified constants in HOL
haftmann
parents: 36943
diff changeset
   359
    (fn thy => fn ss => fn (Const (@{const_name "op ="},_)$x$y) =>
30289
b28caca9157f removed spurious occurrences of old rep_ss;
wenzelm
parents: 29302
diff changeset
   360
        case try Simplifier.the_context ss of
25171
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   361
        SOME ctxt => Option.map (fn neq => neq_to_eq_False OF [neq]) 
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   362
                      (get_fst_success (neq_x_y ctxt x y) names)
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   363
       | NONE => NONE
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   364
    )
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   365
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   366
end
4a9c25bffc9b added Statespace library
schirmer
parents:
diff changeset
   367
end;