src/HOL/Library/sct.ML
changeset 22675 acf10be7dcca
parent 22567 1565d476a9e2
child 22997 d4f3b015b50b
equal deleted inserted replaced
22674:1a610904bbca 22675:acf10be7dcca
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Alexander Krauss, TU Muenchen
     3     Author:     Alexander Krauss, TU Muenchen
     4 
     4 
     5 Tactics for size change termination.
     5 Tactics for size change termination.
     6 *)
     6 *)
     7 signature SCT = 
     7 signature SCT =
     8 sig
     8 sig
     9   val abs_rel_tac : tactic
     9   val abs_rel_tac : tactic
    10   val mk_call_graph : tactic
    10   val mk_call_graph : tactic
    11 end
    11 end
    12 
    12 
    13 structure Sct : SCT = 
    13 structure Sct : SCT =
    14 struct
    14 struct
    15 
    15 
    16 fun matrix [] ys = []
    16 fun matrix [] ys = []
    17   | matrix (x::xs) ys = map (pair x) ys :: matrix xs ys
    17   | matrix (x::xs) ys = map (pair x) ys :: matrix xs ys
    18 
    18 
    19 fun map_matrix f xss = map (map f) xss
    19 fun map_matrix f xss = map (map f) xss
    20 
    20 
    21 val scgT = Sign.read_typ (the_context (), K NONE) "scg"
    21 val scgT = @{typ scg}
    22 val acgT = Sign.read_typ (the_context (), K NONE) "acg"
    22 val acgT = @{typ acg}
    23 
    23 
    24 fun edgeT nT eT = HOLogic.mk_prodT (nT, HOLogic.mk_prodT (eT, nT))
    24 fun edgeT nT eT = HOLogic.mk_prodT (nT, HOLogic.mk_prodT (eT, nT))
    25 fun graphT nT eT = Type ("Graphs.graph", [nT, eT])
    25 fun graphT nT eT = Type ("Graphs.graph", [nT, eT])
    26 
    26 
    27 fun graph_const nT eT = Const ("Graphs.graph.Graph", HOLogic.mk_setT (edgeT nT eT) --> graphT nT eT)
    27 fun graph_const nT eT = Const ("Graphs.graph.Graph", HOLogic.mk_setT (edgeT nT eT) --> graphT nT eT)
    28 
    28 
    29 val stepP_const = "SCT_Interpretation.stepP"
    29 val stepP_const = "SCT_Interpretation.stepP"
    30 val stepP_def = thm "SCT_Interpretation.stepP.simps"
    30 val stepP_def = thm "SCT_Interpretation.stepP.simps"
    31 
    31 
    32 fun mk_stepP RD1 RD2 M1 M2 Rel = 
    32 fun mk_stepP RD1 RD2 M1 M2 Rel =
    33     let val RDT = fastype_of RD1
    33     let val RDT = fastype_of RD1
    34       val MT = fastype_of M1
    34       val MT = fastype_of M1
    35     in 
    35     in
    36       Const (stepP_const, RDT --> RDT --> MT --> MT --> (fastype_of Rel) --> HOLogic.boolT) 
    36       Const (stepP_const, RDT --> RDT --> MT --> MT --> (fastype_of Rel) --> HOLogic.boolT)
    37             $ RD1 $ RD2 $ M1 $ M2 $ Rel 
    37             $ RD1 $ RD2 $ M1 $ M2 $ Rel
    38     end
    38     end
    39 
    39 
    40 val no_stepI = thm "SCT_Interpretation.no_stepI"
    40 val no_stepI = thm "SCT_Interpretation.no_stepI"
    41 
    41 
    42 val approx_const = "SCT_Interpretation.approx"
    42 val approx_const = "SCT_Interpretation.approx"
    43 val approx_empty = thm "SCT_Interpretation.approx_empty"
    43 val approx_empty = thm "SCT_Interpretation.approx_empty"
    44 val approx_less = thm "SCT_Interpretation.approx_less"
    44 val approx_less = thm "SCT_Interpretation.approx_less"
    45 val approx_leq = thm "SCT_Interpretation.approx_leq"
    45 val approx_leq = thm "SCT_Interpretation.approx_leq"
    46 
    46 
    47 fun mk_approx G RD1 RD2 Ms1 Ms2 = 
    47 fun mk_approx G RD1 RD2 Ms1 Ms2 =
    48     let val RDT = fastype_of RD1
    48     let val RDT = fastype_of RD1
    49       val MsT = fastype_of Ms1
    49       val MsT = fastype_of Ms1
    50     in Const (approx_const, scgT --> RDT --> RDT --> MsT --> MsT --> HOLogic.boolT) $ G $ RD1 $ RD2 $ Ms1 $ Ms2 end
    50     in Const (approx_const, scgT --> RDT --> RDT --> MsT --> MsT --> HOLogic.boolT) $ G $ RD1 $ RD2 $ Ms1 $ Ms2 end
    51 
    51 
    52 val sound_int_const = "SCT_Interpretation.sound_int"
    52 val sound_int_const = "SCT_Interpretation.sound_int"
    72 val all_less_Suc = thm "SCT_Interpretation.all_less_Suc"
    72 val all_less_Suc = thm "SCT_Interpretation.all_less_Suc"
    73 
    73 
    74 (* --> Library? *)
    74 (* --> Library? *)
    75 fun del_index n [] = []
    75 fun del_index n [] = []
    76   | del_index n (x :: xs) =
    76   | del_index n (x :: xs) =
    77     if n>0 then x :: del_index (n - 1) xs else xs 
    77     if n>0 then x :: del_index (n - 1) xs else xs
    78 
    78 
    79 (* Lists as finite multisets *)
    79 (* Lists as finite multisets *)
    80 
    80 
    81 fun remove1 eq x [] = []
    81 fun remove1 eq x [] = []
    82   | remove1 eq x (y :: ys) = if eq (x, y) then ys else y :: remove1 eq x ys
    82   | remove1 eq x (y :: ys) = if eq (x, y) then ys else y :: remove1 eq x ys
    89       val (n, body) = Term.dest_abs a
    89       val (n, body) = Term.dest_abs a
    90     in
    90     in
    91       (Free (n, T), body)
    91       (Free (n, T), body)
    92     end
    92     end
    93   | dest_ex _ = raise Match
    93   | dest_ex _ = raise Match
    94                          
    94 
    95 fun dest_all_ex (t as (Const ("Ex",_) $ _)) = 
    95 fun dest_all_ex (t as (Const ("Ex",_) $ _)) =
    96     let
    96     let
    97       val (v,b) = dest_ex t
    97       val (v,b) = dest_ex t
    98       val (vs, b') = dest_all_ex b
    98       val (vs, b') = dest_all_ex b
    99     in
    99     in
   100       (v :: vs, b')
   100       (v :: vs, b')
   101     end
   101     end
   102   | dest_all_ex t = ([],t)
   102   | dest_all_ex t = ([],t)
   103 
   103 
   104 fun dist_vars [] vs = (null vs orelse error "dist_vars"; [])
   104 fun dist_vars [] vs = (null vs orelse error "dist_vars"; [])
   105   | dist_vars (T::Ts) vs = 
   105   | dist_vars (T::Ts) vs =
   106     case find_index (fn v => fastype_of v = T) vs of
   106     case find_index (fn v => fastype_of v = T) vs of
   107       ~1 => Free ("", T) :: dist_vars Ts vs
   107       ~1 => Free ("", T) :: dist_vars Ts vs
   108     |  i => (nth vs i) :: dist_vars Ts (del_index i vs)
   108     |  i => (nth vs i) :: dist_vars Ts (del_index i vs)
   109 
   109 
   110 fun dest_case rebind t =
   110 fun dest_case rebind t =
   111     let
   111     let
   112       val (_ $ _ $ rhs :: _ $ _ $ match :: guards) = HOLogic.dest_conj t
   112       val (_ $ _ $ rhs :: _ $ _ $ match :: guards) = HOLogic.dest_conj t
   113       val guard = case guards of [] => HOLogic.true_const | gs => foldr1 HOLogic.mk_conj gs
   113       val guard = case guards of [] => HOLogic.true_const | gs => foldr1 HOLogic.mk_conj gs
   114     in 
   114     in
   115       foldr1 HOLogic.mk_prod [rebind guard, rebind rhs, rebind match]
   115       foldr1 HOLogic.mk_prod [rebind guard, rebind rhs, rebind match]
   116     end
   116     end
   117 
   117 
   118 fun bind_many [] = I
   118 fun bind_many [] = I
   119   | bind_many vs = FundefLib.tupled_lambda (foldr1 HOLogic.mk_prod vs)
   119   | bind_many vs = FundefLib.tupled_lambda (foldr1 HOLogic.mk_prod vs)
   120 
   120 
   121 (* Builds relation descriptions from a relation definition *)
   121 (* Builds relation descriptions from a relation definition *)
   122 fun mk_reldescs (Abs a) = 
   122 fun mk_reldescs (Abs a) =
   123     let
   123     let
   124       val (_, Abs a') = Term.dest_abs a
   124       val (_, Abs a') = Term.dest_abs a
   125       val (_, b) = Term.dest_abs a'
   125       val (_, b) = Term.dest_abs a'
   126       val cases = HOLogic.dest_disj b
   126       val cases = HOLogic.dest_disj b
   127       val (vss, bs) = split_list (map dest_all_ex cases)
   127       val (vss, bs) = split_list (map dest_all_ex cases)
   128       val unionTs = fold (multi_union (op =)) (map (map fastype_of) vss) []
   128       val unionTs = fold (multi_union (op =)) (map (map fastype_of) vss) []
   129       val rebind = map (bind_many o dist_vars unionTs) vss
   129       val rebind = map (bind_many o dist_vars unionTs) vss
   130                  
   130 
   131       val RDs = map2 dest_case rebind bs
   131       val RDs = map2 dest_case rebind bs
   132     in
   132     in
   133       HOLogic.mk_list (fastype_of (hd RDs)) RDs
   133       HOLogic.mk_list (fastype_of (hd RDs)) RDs
   134     end
   134     end
   135 
   135 
   175       the o Inttab.lookup table
   175       the o Inttab.lookup table
   176     end
   176     end
   177 
   177 
   178 val get_elem = snd o Logic.dest_equals o prop_of
   178 val get_elem = snd o Logic.dest_equals o prop_of
   179 
   179 
   180 fun inst_nums thy i j (t:thm) = 
   180 fun inst_nums thy i j (t:thm) =
   181   instantiate' [] [NONE, NONE, NONE, SOME (cterm_of thy (mk_number i)), NONE, SOME (cterm_of thy (mk_number j))] t
   181   instantiate' [] [NONE, NONE, NONE, SOME (cterm_of thy (mk_number i)), NONE, SOME (cterm_of thy (mk_number j))] t
   182 
   182 
   183 datatype call_fact =
   183 datatype call_fact =
   184    NoStep of thm
   184    NoStep of thm
   185  | Graph of (term * thm)
   185  | Graph of (term * thm)
   202       val N = length Mst1 and M = length Mst2
   202       val N = length Mst1 and M = length Mst2
   203       val saved_state = HOLogic.mk_Trueprop (mk_stepP RD1 RD2 mvar1 mvar2 relvar)
   203       val saved_state = HOLogic.mk_Trueprop (mk_stepP RD1 RD2 mvar1 mvar2 relvar)
   204                          |> cterm_of thy
   204                          |> cterm_of thy
   205                          |> Goal.init
   205                          |> Goal.init
   206                          |> CLASIMPSET auto_tac |> Seq.hd
   206                          |> CLASIMPSET auto_tac |> Seq.hd
   207                          
   207 
   208       val no_step = saved_state 
   208       val no_step = saved_state
   209                       |> forall_intr (cterm_of thy relvar)
   209                       |> forall_intr (cterm_of thy relvar)
   210                       |> forall_elim (cterm_of thy (Abs ("", HOLogic.natT, Abs ("", HOLogic.natT, HOLogic.false_const))))
   210                       |> forall_elim (cterm_of thy (Abs ("", HOLogic.natT, Abs ("", HOLogic.natT, HOLogic.false_const))))
   211                       |> CLASIMPSET auto_tac |> Seq.hd
   211                       |> CLASIMPSET auto_tac |> Seq.hd
   212 
   212 
   213     in
   213     in
   214       if Thm.no_prems no_step
   214       if Thm.no_prems no_step
   215       then NoStep (Goal.finish no_step RS no_stepI)
   215       then NoStep (Goal.finish no_step RS no_stepI)
   216       else
   216       else
   217         let
   217         let
   218           fun set_m1 i =
   218           fun set_m1 i =
   219               let 
   219               let
   220                 val M1 = nth Mst1 i
   220                 val M1 = nth Mst1 i
   221                 val with_m1 = saved_state
   221                 val with_m1 = saved_state
   222                                 |> forall_intr (cterm_of thy mvar1)
   222                                 |> forall_intr (cterm_of thy mvar1)
   223                                 |> forall_elim (cterm_of thy M1)
   223                                 |> forall_elim (cterm_of thy M1)
   224                                 |> CLASIMPSET auto_tac |> Seq.hd
   224                                 |> CLASIMPSET auto_tac |> Seq.hd
   225 
   225 
   226                 fun set_m2 j = 
   226                 fun set_m2 j =
   227                     let 
   227                     let
   228                       val M2 = nth Mst2 j
   228                       val M2 = nth Mst2 j
   229                       val with_m2 = with_m1
   229                       val with_m2 = with_m1
   230                                       |> forall_intr (cterm_of thy mvar2)
   230                                       |> forall_intr (cterm_of thy mvar2)
   231                                       |> forall_elim (cterm_of thy M2)
   231                                       |> forall_elim (cterm_of thy M2)
   232                                       |> CLASIMPSET auto_tac |> Seq.hd
   232                                       |> CLASIMPSET auto_tac |> Seq.hd
   239                                      #> forall_elim (cterm_of thy lesseq_nat_const)
   239                                      #> forall_elim (cterm_of thy lesseq_nat_const)
   240                                      #> CLASIMPSET auto_tac #> Seq.hd
   240                                      #> CLASIMPSET auto_tac #> Seq.hd
   241 
   241 
   242                       val thm1 = decr with_m2
   242                       val thm1 = decr with_m2
   243                     in
   243                     in
   244                       if Thm.no_prems thm1 
   244                       if Thm.no_prems thm1
   245                       then ((rtac (inst_nums thy i j approx_less) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm1) 1))
   245                       then ((rtac (inst_nums thy i j approx_less) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm1) 1))
   246                       else let val thm2 = decreq with_m2 in
   246                       else let val thm2 = decreq with_m2 in
   247                              if Thm.no_prems thm2 
   247                              if Thm.no_prems thm2
   248                              then ((rtac (inst_nums thy i j approx_leq) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm2) 1))
   248                              then ((rtac (inst_nums thy i j approx_leq) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm2) 1))
   249                              else all_tac end
   249                              else all_tac end
   250                     end
   250                     end
   251               in set_m2 end
   251               in set_m2 end
   252 
   252 
   253           val goal = HOLogic.mk_Trueprop (mk_approx (Var (("G", 0), scgT)) RD1 RD2 Ms1 Ms2)
   253           val goal = HOLogic.mk_Trueprop (mk_approx (Var (("G", 0), scgT)) RD1 RD2 Ms1 Ms2)
   254 
   254 
   255           val tac = (EVERY (map (fn n => EVERY (map (set_m1 n) (0 upto M - 1))) (0 upto N - 1)))
   255           val tac = (EVERY (map (fn n => EVERY (map (set_m1 n) (0 upto M - 1))) (0 upto N - 1)))
   256                       THEN (rtac approx_empty 1)
   256                       THEN (rtac approx_empty 1)
   257 
   257 
   258           val approx_thm = goal 
   258           val approx_thm = goal
   259                     |> cterm_of thy
   259                     |> cterm_of thy
   260                     |> Goal.init
   260                     |> Goal.init
   261                     |> tac |> Seq.hd
   261                     |> tac |> Seq.hd
   262                     |> Goal.finish
   262                     |> Goal.finish
   263 
   263 
   277   | dest_set (Const ("insert", _) $ x $ xs) = x :: dest_set xs
   277   | dest_set (Const ("insert", _) $ x $ xs) = x :: dest_set xs
   278 
   278 
   279 val pr_graph = Sign.string_of_term
   279 val pr_graph = Sign.string_of_term
   280 fun pr_matrix thy = map_matrix (fn Graph (G, _) => pr_graph thy G | _ => "X")
   280 fun pr_matrix thy = map_matrix (fn Graph (G, _) => pr_graph thy G | _ => "X")
   281 
   281 
   282 val in_graph_tac = 
   282 val in_graph_tac =
   283     simp_tac (HOL_basic_ss addsimps has_edge_simps) 1
   283     simp_tac (HOL_basic_ss addsimps has_edge_simps) 1
   284     THEN SIMPSET (fn x => simp_tac x 1) (* FIXME reduce simpset *)
   284     THEN SIMPSET (fn x => simp_tac x 1) (* FIXME reduce simpset *)
   285 
   285 
   286 fun approx_tac (NoStep thm) = rtac disjI1 1 THEN rtac thm 1
   286 fun approx_tac (NoStep thm) = rtac disjI1 1 THEN rtac thm 1
   287   | approx_tac (Graph (G, thm)) =
   287   | approx_tac (Graph (G, thm)) =
   288     rtac disjI2 1 
   288     rtac disjI2 1
   289     THEN rtac exI 1
   289     THEN rtac exI 1
   290     THEN rtac conjI 1
   290     THEN rtac conjI 1
   291     THEN rtac thm 2
   291     THEN rtac thm 2
   292     THEN in_graph_tac
   292     THEN in_graph_tac
   293 
   293 
   294 fun all_less_tac [] = rtac all_less_zero 1
   294 fun all_less_tac [] = rtac all_less_zero 1
   295   | all_less_tac (t :: ts) = rtac all_less_Suc 1 
   295   | all_less_tac (t :: ts) = rtac all_less_Suc 1
   296                                   THEN simp_nth_tac 1
   296                                   THEN simp_nth_tac 1
   297                                   THEN t 
   297                                   THEN t
   298                                   THEN all_less_tac ts
   298                                   THEN all_less_tac ts
   299 
   299 
   300 
   300 
   301 val length_const = "Nat.size"
   301 val length_const = "Nat.size"
   302 fun mk_length l = Const (length_const, fastype_of l --> HOLogic.natT) $ l
   302 fun mk_length l = Const (length_const, fastype_of l --> HOLogic.natT) $ l
   308     let
   308     let
   309       val thy = theory_of_thm st
   309       val thy = theory_of_thm st
   310       val _ $ _ $ RDlist $ _ = HOLogic.dest_Trueprop (hd (prems_of st))
   310       val _ $ _ $ RDlist $ _ = HOLogic.dest_Trueprop (hd (prems_of st))
   311 
   311 
   312       val RDs = HOLogic.dest_list RDlist
   312       val RDs = HOLogic.dest_list RDlist
   313       val n = length RDs 
   313       val n = length RDs
   314 
   314 
   315       val Mss = map measures_of RDs
   315       val Mss = map measures_of RDs
   316 
   316 
   317       val domT = domain_type (fastype_of (hd (hd Mss)))
   317       val domT = domain_type (fastype_of (hd (hd Mss)))
   318 
   318 
   327       val mlens = map length Mss
   327       val mlens = map length Mss
   328 
   328 
   329       val indices = (n - 1 downto 0)
   329       val indices = (n - 1 downto 0)
   330       val pairs = matrix indices indices
   330       val pairs = matrix indices indices
   331       val parts = map_matrix (fn (n,m) =>
   331       val parts = map_matrix (fn (n,m) =>
   332                                  (timeap_msg (string_of_int n ^ "," ^ string_of_int m) 
   332                                  (timeap_msg (string_of_int n ^ "," ^ string_of_int m)
   333                                              (setup_probe_goal thy domT Dtab Mtab) (n,m))) pairs
   333                                              (setup_probe_goal thy domT Dtab Mtab) (n,m))) pairs
   334 
   334 
   335 
   335 
   336       val s = fold_index (fn (i, cs) => fold_index (fn (j, Graph (G, _)) => prefix ("(" ^ string_of_int i ^ "," ^ string_of_int j ^ "): " ^
   336       val s = fold_index (fn (i, cs) => fold_index (fn (j, Graph (G, _)) => prefix ("(" ^ string_of_int i ^ "," ^ string_of_int j ^ "): " ^
   337                                                                             pr_graph thy G ^ ",\n")
   337                                                                             pr_graph thy G ^ ",\n")
   338                                                      | _ => I) cs) parts ""
   338                                                      | _ => I) cs) parts ""
   339       val _ = Output.warning s
   339       val _ = Output.warning s
   340   
   340 
   341 
   341 
   342       val ACG = map_filter (fn (Graph (G, _),(m, n)) => SOME (mk_edge (mk_number m) G (mk_number n)) | _ => NONE) (flat parts ~~ flat pairs)
   342       val ACG = map_filter (fn (Graph (G, _),(m, n)) => SOME (mk_edge (mk_number m) G (mk_number n)) | _ => NONE) (flat parts ~~ flat pairs)
   343                     |> mk_set (edgeT HOLogic.natT scgT)
   343                     |> mk_set (edgeT HOLogic.natT scgT)
   344                     |> curry op $ (graph_const HOLogic.natT scgT)
   344                     |> curry op $ (graph_const HOLogic.natT scgT)
   345 
   345 
   346 
   346 
   347       val sound_int_goal = HOLogic.mk_Trueprop (mk_sound_int ACG RDlist mfuns)
   347       val sound_int_goal = HOLogic.mk_Trueprop (mk_sound_int ACG RDlist mfuns)
   348 
   348 
   349       val tac = 
   349       val tac =
   350           (SIMPSET (unfold_tac [sound_int_def, len_simp]))
   350           (SIMPSET (unfold_tac [sound_int_def, len_simp]))
   351             THEN all_less_tac (map (all_less_tac o map approx_tac) parts)
   351             THEN all_less_tac (map (all_less_tac o map approx_tac) parts)
   352     in
   352     in
   353       tac (instantiate' [] [SOME (cterm_of thy ACG), SOME (cterm_of thy mfuns)] st)
   353       tac (instantiate' [] [SOME (cterm_of thy ACG), SOME (cterm_of thy mfuns)] st)
   354     end
   354     end
   355                   
   355 
   356 
   356 
   357 end                   
   357 end
   358 
   358 
   359 
   359 
   360 
   360 
   361 
   361 
   362 
   362 
   363 
   363 
       
   364