src/HOL/BNF/Tools/bnf_fp_rec_sugar_util.ML
changeset 54068 447354985f6a
parent 54067 7be49e2bfccc
child 54069 3fd3b1683d2b
equal deleted inserted replaced
54067:7be49e2bfccc 54068:447354985f6a
    49      nested_maps: thm list,
    49      nested_maps: thm list,
    50      nested_map_idents: thm list,
    50      nested_map_idents: thm list,
    51      nested_map_comps: thm list,
    51      nested_map_comps: thm list,
    52      ctr_specs: corec_ctr_spec list}
    52      ctr_specs: corec_ctr_spec list}
    53 
    53 
    54   val mk_conjs: term list -> term
       
    55   val mk_disjs: term list -> term
       
    56   val s_not: term -> term
    54   val s_not: term -> term
    57   val s_not_conj: term list -> term list
    55   val s_not_conj: term list -> term list
       
    56   val s_conjs: term list -> term
       
    57   val s_disjs: term list -> term
       
    58   val s_dnf: term list list -> term list
    58 
    59 
    59   val massage_indirect_rec_call: Proof.context -> (term -> bool) -> (typ -> typ -> term -> term) ->
    60   val massage_indirect_rec_call: Proof.context -> (term -> bool) -> (typ -> typ -> term -> term) ->
    60     typ list -> term -> term -> term -> term
    61     typ list -> term -> term -> term -> term
    61   val massage_direct_corec_call: Proof.context -> (term -> bool) -> (typ list -> term -> term) ->
    62   val massage_direct_corec_call: Proof.context -> (term -> bool) -> (typ list -> term -> term) ->
    62     typ list -> term -> term
    63     typ list -> term -> term
   158   | s_not (@{const disj} $ t $ u) = @{const conj} $ s_not t $ s_not u
   159   | s_not (@{const disj} $ t $ u) = @{const conj} $ s_not t $ s_not u
   159   | s_not (@{const implies} $ t $ u) = @{const conj} $ t $ s_not u
   160   | s_not (@{const implies} $ t $ u) = @{const conj} $ t $ s_not u
   160   | s_not t = @{const Not} $ t;
   161   | s_not t = @{const Not} $ t;
   161 
   162 
   162 val s_not_conj = conjuncts_s o s_not o mk_conjs;
   163 val s_not_conj = conjuncts_s o s_not o mk_conjs;
       
   164 
       
   165 fun s_conj c @{const True} = c
       
   166   | s_conj c d = HOLogic.mk_conj (c, d);
       
   167 
       
   168 fun propagate_unit_pos u cs = if member (op aconv) cs u then [@{const False}] else cs;
       
   169 
       
   170 fun propagate_unit_neg not_u cs = remove (op aconv) not_u cs;
       
   171 
       
   172 fun propagate_units css =
       
   173   (case List.partition (can the_single) css of
       
   174      ([], _) => css
       
   175    | ([u] :: uss, css') =>
       
   176      [u] :: propagate_units (map (propagate_unit_neg (s_not u))
       
   177        (map (propagate_unit_pos u) (uss @ css'))));
       
   178 
       
   179 fun s_conjs cs =
       
   180   if member (op aconv) cs @{const False} then @{const False}
       
   181   else mk_conjs (remove (op aconv) @{const True} cs);
       
   182 
       
   183 fun s_disjs ds =
       
   184   if member (op aconv) ds @{const True} then @{const True}
       
   185   else mk_disjs (remove (op aconv) @{const False} ds);
       
   186 
       
   187 fun s_dnf css0 =
       
   188   let val css = propagate_units css0 in
       
   189     if null css then
       
   190       [@{const False}]
       
   191     else if exists null css then
       
   192       []
       
   193     else
       
   194       map (fn c :: cs => (c, cs)) css
       
   195       |> AList.coalesce (op =)
       
   196       |> map (fn (c, css) => c :: s_dnf css)
       
   197       |> (fn [cs] => cs | css => [s_disjs (map s_conjs css)])
       
   198   end;
   163 
   199 
   164 fun factor_out_types ctxt massage destU U T =
   200 fun factor_out_types ctxt massage destU U T =
   165   (case try destU U of
   201   (case try destU U of
   166     SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt
   202     SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt
   167   | NONE => invalid_map ctxt);
   203   | NONE => invalid_map ctxt);