src/HOL/Nominal/nominal_induct.ML
author urbanc
Mon, 07 Nov 2005 10:47:25 +0100
changeset 18099 e956b04fea22
parent 18052 004515accc10
child 18157 72e1956440ad
permissions -rw-r--r--
fixed bug with nominal induct - the bug occured in rule inductions when the goal did not use all variables from the relation over which the induction was done
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     1
(* $Id$ *)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     2
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     3
local
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     4
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     5
(* A function that takes a list of Variables and a term t;                    *)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     6
(* it builds up an abstraction of the Variables packaged in a tuple(!)        *)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     7
(* over the term t.                                                           *)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     8
(* E.g  tuple_lambda [] t        produces %x . t where x is a dummy Variable  *) 
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
     9
(*      tuple_lambda [a] t       produces %a . t                              *) 
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    10
(*      tuple_lambda [a,b,c] t   produces %(a,b,c). t                         *)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    11
18052
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    12
fun tuple_lambda [] t  = Abs ("x", HOLogic.unitT, t)
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    13
  | tuple_lambda [x] t = lambda x t
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    14
  | tuple_lambda (x::xs) t =
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    15
    let
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    16
        val t' = tuple_lambda xs t;
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    17
        val Type ("fun", [T,U]) = fastype_of t';
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    18
    in
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    19
        HOLogic.split_const (fastype_of x,T,U) $ lambda x t'
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    20
    end; 
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    21
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    22
fun find_var frees name =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    23
  (case Library.find_first (equal name o fst o dest_Free) frees of
18099
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    24
    NONE =>   error ("No such Variable in term: " ^ quote name) 
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    25
  | SOME v => v);
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    26
18052
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    27
(* - names specifies the variables that are involved in the *)
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    28
(*   induction                                              *)
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    29
(* - rule is the induction rule to be applied               *)              
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    30
fun nominal_induct_tac (names, rule) facts state =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    31
  let
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    32
    val sg     = Thm.sign_of_thm state;
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    33
    val cert   = Thm.cterm_of sg;
18099
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    34
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    35
    val facts1 = Library.take (1, facts);
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    36
    val facts2 = Library.drop (1, facts);
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    37
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    38
    val goal :: _ = Thm.prems_of state;  (*exception Subscript*)
18099
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    39
    val frees  = foldl Term.add_term_frees [] (goal :: map concl_of facts1);
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    40
    val frees' = filter_out (fn Free (x, _) => exists (equal x) names) frees;
18099
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    41
    val vars = map (find_var frees) names; 
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    42
                 (* FIXME - check what one can do in case of *)
e956b04fea22 fixed bug with nominal induct
urbanc
parents: 18052
diff changeset
    43
                 (* rule inductions                          *)
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    44
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    45
    fun inst_rule rule =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    46
      let
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    47
        val concl_vars = map Var (rev (Term.add_vars (Thm.concl_of rule) []));
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    48
        val (P :: ts, x) = split_last concl_vars
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    49
          handle Empty => error "Malformed conclusion of induction rule"
18052
004515accc10 tunings of some comments (nothing serious)
urbanc
parents: 17870
diff changeset
    50
               | Bind  => error "Malformed conclusion of induction rule";
17870
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    51
      in
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    52
        cterm_instantiate
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    53
          ((cert P, cert (fold_rev lambda vars (tuple_lambda frees' (HOLogic.dest_Trueprop goal)))) ::
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    54
           (cert x, cert (if null frees' then HOLogic.unit else foldr1 HOLogic.mk_prod frees')) ::
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    55
           (map cert ts ~~ map cert vars)) rule
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    56
      end;
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    57
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    58
    val simplify_rule =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    59
      Simplifier.full_simplify (HOL_basic_ss addsimps
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    60
        [split_conv, split_paired_All, split_paired_all]);
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    61
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    62
  in
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    63
    rule
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    64
    |> inst_rule
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    65
    |> Method.multi_resolve facts1
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    66
    |> Seq.map simplify_rule
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    67
    |> Seq.map (RuleCases.save rule)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    68
    |> Seq.map RuleCases.add
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    69
    |> Seq.map (fn (r, (cases, _)) =>
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    70
        HEADGOAL (Method.insert_tac facts2 THEN' Tactic.rtac r) state
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    71
        |> Seq.map (rpair (RuleCases.make false NONE (sg, Thm.prop_of r) cases)))
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    72
    |> Seq.flat
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    73
  end
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    74
  handle Subscript => Seq.empty;
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    75
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    76
val rule_spec = Scan.lift (Args.$$$ "rule" -- Args.colon) |-- Attrib.local_thm;
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    77
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    78
val nominal_induct_args =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    79
  Scan.repeat (Scan.unless rule_spec (Scan.lift Args.name)) -- rule_spec;
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    80
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    81
in
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    82
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    83
val nominal_induct_method =
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    84
  Method.RAW_METHOD_CASES o nominal_induct_tac oo (#2 oo Method.syntax nominal_induct_args);
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    85
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    86
(* nominal_induc_method needs to have the type
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    87
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    88
   Args.src -> Proof.context -> Proof.method
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    89
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    90
   CHECK THAT
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    91
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    92
*)
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    93
c35381811d5c Initial revision.
berghofe
parents:
diff changeset
    94
end;