added massaging function for primcorec code equations
authorblanchet
Thu, 19 Sep 2013 01:09:25 +0200
changeset 54863d41a30db83d9
parent 54862 9e64151359e8
child 54864 1d88a7ee4e3e
added massaging function for primcorec code equations
src/HOL/BNF/Tools/bnf_fp_rec_sugar_util.ML
     1.1 --- a/src/HOL/BNF/Tools/bnf_fp_rec_sugar_util.ML	Thu Sep 19 01:09:25 2013 +0200
     1.2 +++ b/src/HOL/BNF/Tools/bnf_fp_rec_sugar_util.ML	Thu Sep 19 01:09:25 2013 +0200
     1.3 @@ -57,6 +57,8 @@
     1.4      term
     1.5    val massage_indirect_corec_call: Proof.context -> (term -> bool) ->
     1.6      (typ -> typ -> term -> term) -> typ list -> typ -> term -> term
     1.7 +  val massage_corec_code_rhs: Proof.context -> (term -> bool) -> (term -> term list -> term) ->
     1.8 +    typ list -> typ -> term -> term
     1.9    val rec_specs_of: binding list -> typ list -> typ list -> (term -> int list) ->
    1.10      ((term * term list list) list) list -> local_theory ->
    1.11      (bool * rec_spec list * typ list * thm * thm list) * local_theory
    1.12 @@ -126,9 +128,6 @@
    1.13    error ("Ill-formed recursive call: " ^ quote (Syntax.string_of_term ctxt t));
    1.14  fun ill_formed_corec_call ctxt t =
    1.15    error ("Ill-formed corecursive call: " ^ quote (Syntax.string_of_term ctxt t));
    1.16 -fun ill_formed_corec_code_rhs ctxt t =
    1.17 -  error ("Ill-formed corecursive equation right-hand side: " ^
    1.18 -    quote (Syntax.string_of_term ctxt t));
    1.19  fun invalid_map ctxt t =
    1.20    error ("Invalid map function in " ^ quote (Syntax.string_of_term ctxt t));
    1.21  fun unexpected_rec_call ctxt t =
    1.22 @@ -196,8 +195,9 @@
    1.23      massage_call
    1.24    end;
    1.25  
    1.26 -fun massage_let_and_if ctxt check_cond massage_leaf U =
    1.27 +fun massage_let_and_if ctxt has_call massage_leaf U =
    1.28    let
    1.29 +    val check_cond = ((not o has_call) orf unexpected_corec_call ctxt);
    1.30      fun massage_rec t =
    1.31        (case Term.strip_comb t of
    1.32          (Const (@{const_name Let}, _), [arg1, arg2]) => massage_rec (betapply (arg2, arg1))
    1.33 @@ -209,8 +209,7 @@
    1.34    end;
    1.35  
    1.36  fun massage_direct_corec_call ctxt has_call massage_direct_call U t =
    1.37 -  massage_let_and_if ctxt ((not o has_call) orf unexpected_corec_call ctxt) massage_direct_call
    1.38 -    U t;
    1.39 +  massage_let_and_if ctxt has_call massage_direct_call U t;
    1.40  
    1.41  fun massage_indirect_corec_call ctxt has_call massage_direct_call bound_Ts U t =
    1.42    let
    1.43 @@ -246,30 +245,59 @@
    1.44          handle AINT_NO_MAP _ => check_and_massage_unapplied_direct_call U T t;
    1.45  
    1.46      fun massage_call U T =
    1.47 -      massage_let_and_if ctxt ((not o has_call) orf unexpected_corec_call ctxt)
    1.48 -        (fn t =>
    1.49 -            (case U of
    1.50 -              Type (s, Us) =>
    1.51 -              (case try (dest_ctr ctxt s) t of
    1.52 -                SOME (f, args) =>
    1.53 -                let val f' = mk_ctr Us f in
    1.54 -                  list_comb (f', map3 massage_call (binder_types (typof f')) (map typof args) args)
    1.55 -                end
    1.56 -              | NONE =>
    1.57 -                (case t of
    1.58 -                  t1 $ t2 =>
    1.59 -                  (if has_call t2 then
    1.60 -                    check_and_massage_direct_call U T t
    1.61 -                  else
    1.62 -                    massage_map U T t1 $ t2
    1.63 -                    handle AINT_NO_MAP _ => check_and_massage_direct_call U T t)
    1.64 -                | _ => check_and_massage_direct_call U T t))
    1.65 -            | _ => ill_formed_corec_call ctxt t))
    1.66 -        U
    1.67 +      massage_let_and_if ctxt has_call (fn t =>
    1.68 +        (case U of
    1.69 +          Type (s, Us) =>
    1.70 +          (case try (dest_ctr ctxt s) t of
    1.71 +            SOME (f, args) =>
    1.72 +            let val f' = mk_ctr Us f in
    1.73 +              list_comb (f', map3 massage_call (binder_types (typof f')) (map typof args) args)
    1.74 +            end
    1.75 +          | NONE =>
    1.76 +            (case t of
    1.77 +              t1 $ t2 =>
    1.78 +              (if has_call t2 then
    1.79 +                check_and_massage_direct_call U T t
    1.80 +              else
    1.81 +                massage_map U T t1 $ t2
    1.82 +                handle AINT_NO_MAP _ => check_and_massage_direct_call U T t)
    1.83 +            | _ => check_and_massage_direct_call U T t))
    1.84 +        | _ => ill_formed_corec_call ctxt t)) U
    1.85    in
    1.86      massage_call U (typof t) t
    1.87    end;
    1.88  
    1.89 +fun explode_ctr_term ctxt s Ts t =
    1.90 +  (case fp_sugar_of ctxt s of
    1.91 +    SOME fp_sugar =>
    1.92 +    let
    1.93 +      val T = Type (s, Ts);
    1.94 +      val x = Bound 0;
    1.95 +      val {ctrs = ctrs0, discs = discs0, selss = selss0, ...} = of_fp_sugar #ctr_sugars fp_sugar;
    1.96 +      val ctrs = map (mk_ctr Ts) ctrs0;
    1.97 +      val discs = map (mk_disc_or_sel Ts) discs0;
    1.98 +      val selss = map (map (mk_disc_or_sel Ts)) selss0;
    1.99 +      val xdiscs = map (rapp x) discs;
   1.100 +      val xselss = map (map (rapp x)) selss;
   1.101 +      val xsel_ctrs = map2 (curry Term.list_comb) ctrs xselss;
   1.102 +      val xif = mk_IfN T xdiscs xsel_ctrs;
   1.103 +    in
   1.104 +      Const (@{const_name Let}, T --> (T --> T) --> T) $ t $ Abs (Name.uu, T, xif)
   1.105 +    end
   1.106 +  | NONE => raise Fail "explode_ctr_term");
   1.107 +
   1.108 +fun massage_corec_code_rhs ctxt has_call massage_ctr bound_Ts U t =
   1.109 +  let val typof = curry fastype_of1 bound_Ts in
   1.110 +    (case typof t of
   1.111 +      T as Type (s, Ts) =>
   1.112 +      massage_let_and_if ctxt has_call (fn t =>
   1.113 +        (case try (dest_ctr ctxt s) t of
   1.114 +          SOME (f, args) => massage_ctr f args
   1.115 +        | NONE => massage_let_and_if ctxt has_call (uncurry massage_ctr o Term.strip_comb) T
   1.116 +            (explode_ctr_term ctxt s Ts t))) U t
   1.117 +    | _ => raise Fail "massage_corec_code_rhs")
   1.118 +  end;
   1.119 +
   1.120  fun indexed xs h = let val h' = h + length xs in (h upto h' - 1, h') end;
   1.121  fun indexedd xss = fold_map indexed xss;
   1.122  fun indexeddd xsss = fold_map indexedd xsss;