Quot/quotient_term.ML
changeset 779 3b21b24a5fb6
parent 776 d1064fa29424
child 782 86c7ed9f354f
equal deleted inserted replaced
778:54f186bb5e3e 779:3b21b24a5fb6
    19 
    19 
    20 open Quotient_Info;
    20 open Quotient_Info;
    21 
    21 
    22 exception LIFT_MATCH of string
    22 exception LIFT_MATCH of string
    23 
    23 
    24 (* Calculates the aggregate abs and rep functions for a given type; *) 
    24 (*******************************)
    25 (* repF is for constants' arguments; absF is for constants;         *)
    25 (* Aggregate Rep/Abs Functions *)
    26 (* function types need to be treated specially, since repF and absF *)
    26 (*******************************)
    27 (* change                                                           *)
    27 
       
    28 (* The flag repF is for types in negative position, while absF is   *) 
       
    29 (* for types in positive position. Because of this, function types  *)
       
    30 (* need to be treated specially, since there the polarity changes.  *)
    28 
    31 
    29 datatype flag = absF | repF
    32 datatype flag = absF | repF
    30 
    33 
    31 fun negF absF = repF
    34 fun negF absF = repF
    32   | negF repF = absF
    35   | negF repF = absF
    36 fun mk_compose flag (trm1, trm2) = 
    39 fun mk_compose flag (trm1, trm2) = 
    37   case flag of
    40   case flag of
    38     absF => Const (@{const_name "comp"}, dummyT) $ trm1 $ trm2
    41     absF => Const (@{const_name "comp"}, dummyT) $ trm1 $ trm2
    39   | repF => Const (@{const_name "comp"}, dummyT) $ trm2 $ trm1
    42   | repF => Const (@{const_name "comp"}, dummyT) $ trm2 $ trm1
    40 
    43 
    41 fun absrep_fun_aux lthy s fs =
    44 fun get_map ctxt ty_str =
    42 let
    45 let
    43   val thy = ProofContext.theory_of lthy
    46   val thy = ProofContext.theory_of ctxt
    44   val exc = LIFT_MATCH (space_implode " " ["absrep_fun_aux: no map for type", quote s, "."])
    47   val exc = LIFT_MATCH (space_implode " " ["absrep_fun: no map for type", quote ty_str, "."])
    45   val info = maps_lookup thy s handle NotFound => raise exc
    48   val info = maps_lookup thy ty_str handle NotFound => raise exc
    46 in
    49 in
    47   list_comb (Const (#mapfun info, dummyT), fs)
    50   Const (#mapfun info, dummyT)
    48 end
    51 end
    49 
    52 
    50 fun get_const flag lthy _ qty =
    53 fun get_absrep_const flag ctxt _ qty =
    51 (* FIXME: check here that the type-constructors of _ and qty are related *)
    54 (* FIXME: check here that the type-constructors of _ and qty are related *)
    52 let
    55 let
    53   val thy = ProofContext.theory_of lthy
    56   val thy = ProofContext.theory_of ctxt
    54   val qty_name = Long_Name.base_name (fst (dest_Type qty))
    57   val qty_name = Long_Name.base_name (fst (dest_Type qty))
    55 in
    58 in
    56   case flag of
    59   case flag of
    57     absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT)
    60     absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT)
    58   | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT)
    61   | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT)
    59 end
    62 end
    60 
    63 
    61 fun absrep_fun flag lthy (rty, qty) =
    64 fun absrep_fun flag ctxt (rty, qty) =
    62   if rty = qty then mk_identity qty else
    65   if rty = qty then mk_identity qty else
    63   case (rty, qty) of
    66   case (rty, qty) of
    64     (Type ("fun", [ty1, ty2]), Type ("fun", [ty1', ty2'])) =>
    67     (Type ("fun", [ty1, ty2]), Type ("fun", [ty1', ty2'])) =>
    65      let
    68       let
    66        val fs_ty1 = absrep_fun (negF flag) lthy (ty1, ty1')
    69         val arg1 = absrep_fun (negF flag) ctxt (ty1, ty1')
    67        val fs_ty2 = absrep_fun flag lthy (ty2, ty2')
    70         val arg2 = absrep_fun flag ctxt (ty2, ty2')
    68      in
    71       in
    69        absrep_fun_aux lthy "fun" [fs_ty1, fs_ty2]
    72         list_comb (get_map ctxt "fun", [arg1, arg2])
    70      end
    73       end
    71   | (Type (s, _), Type (s', [])) =>
    74   | (Type (s, _), Type (s', [])) =>
    72      if s = s'
    75       if s = s'
    73      then mk_identity qty
    76       then mk_identity qty
    74      else get_const flag lthy rty qty
    77       else get_absrep_const flag ctxt rty qty
    75   | (Type (s, tys), Type (s', tys')) =>
    78   | (Type (s, tys), Type (s', tys')) =>
    76      let
    79       let
    77         val args = map (absrep_fun flag lthy) (tys ~~ tys')
    80         val args = map (absrep_fun flag ctxt) (tys ~~ tys')
    78      in
    81         val result = list_comb (get_map ctxt s, args)
       
    82       in
    79         if s = s'
    83         if s = s'
    80         then absrep_fun_aux lthy s args
    84         then result
    81         else mk_compose flag (get_const flag lthy rty qty, absrep_fun_aux lthy s args)
    85         else mk_compose flag (get_absrep_const flag ctxt rty qty, result)
    82      end
    86       end
    83   | (TFree x, TFree x') =>
    87   | (TFree x, TFree x') =>
    84      if x = x'
    88       if x = x'
    85      then mk_identity qty
    89       then mk_identity qty
    86      else raise (LIFT_MATCH "absrep_fun (frees)")
    90       else raise (LIFT_MATCH "absrep_fun (frees)")
    87   | (TVar _, TVar _) => raise (LIFT_MATCH "absrep_fun (vars)")
    91   | (TVar _, TVar _) => raise (LIFT_MATCH "absrep_fun (vars)")
    88   | _ => raise (LIFT_MATCH "absrep_fun (default)")
    92   | _ => raise (LIFT_MATCH "absrep_fun (default)")
    89 
    93 
    90 fun absrep_fun_chk flag lthy (rty, qty) =
    94 fun absrep_fun_chk flag ctxt (rty, qty) =
    91   absrep_fun flag lthy (rty, qty)
    95   absrep_fun flag ctxt (rty, qty)
    92   |> Syntax.check_term lthy
    96   |> Syntax.check_term ctxt
    93 
    97 
    94 (*
    98 
    95 Regularizing an rtrm means:
    99 (* Regularizing an rtrm means:
    96  
   100  
    97  - Quantifiers over types that need lifting are replaced 
   101  - Quantifiers over types that need lifting are replaced 
    98    by bounded quantifiers, for example:
   102    by bounded quantifiers, for example:
    99 
   103 
   100       All P  ----> All (Respects R) P
   104       All P  ----> All (Respects R) P
   118    for more complicated types of A and B
   122    for more complicated types of A and B
   119 *)
   123 *)
   120 
   124 
   121 (* builds the aggregate equivalence relation *)
   125 (* builds the aggregate equivalence relation *)
   122 (* that will be the argument of Respects     *)
   126 (* that will be the argument of Respects     *)
   123 fun mk_resp_arg lthy (rty, qty) =
   127 fun mk_resp_arg ctxt (rty, qty) =
   124 let
   128 let
   125   val thy = ProofContext.theory_of lthy
   129   val thy = ProofContext.theory_of ctxt
   126 in  
   130 in  
   127   if rty = qty
   131   if rty = qty
   128   then HOLogic.eq_const rty
   132   then HOLogic.eq_const rty
   129   else
   133   else
   130     case (rty, qty) of
   134     case (rty, qty) of
   132        if s = s' 
   136        if s = s' 
   133        then 
   137        then 
   134          let
   138          let
   135            val exc = LIFT_MATCH ("mk_resp_arg (no map function found for type " ^ s) 
   139            val exc = LIFT_MATCH ("mk_resp_arg (no map function found for type " ^ s) 
   136            val map_info = maps_lookup thy s handle NotFound => raise exc
   140            val map_info = maps_lookup thy s handle NotFound => raise exc
   137            val args = map (mk_resp_arg lthy) (tys ~~ tys')
   141            val args = map (mk_resp_arg ctxt) (tys ~~ tys')
   138          in
   142          in
   139            list_comb (Const (#relfun map_info, dummyT), args) 
   143            list_comb (Const (#relfun map_info, dummyT), args) 
   140          end  
   144          end  
   141        else 
   145        else 
   142          let  
   146          let  
   178 (* - the result still contains dummyTs          *)
   182 (* - the result still contains dummyTs          *)
   179 (*                                              *)
   183 (*                                              *)
   180 (* - for regularisation we do not need any      *)
   184 (* - for regularisation we do not need any      *)
   181 (*   special treatment of bound variables       *)
   185 (*   special treatment of bound variables       *)
   182 
   186 
   183 fun regularize_trm lthy (rtrm, qtrm) =
   187 fun regularize_trm ctxt (rtrm, qtrm) =
   184   case (rtrm, qtrm) of
   188   case (rtrm, qtrm) of
   185     (Abs (x, ty, t), Abs (_, ty', t')) =>
   189     (Abs (x, ty, t), Abs (_, ty', t')) =>
   186        let
   190        let
   187          val subtrm = Abs(x, ty, regularize_trm lthy (t, t'))
   191          val subtrm = Abs(x, ty, regularize_trm ctxt (t, t'))
   188        in
   192        in
   189          if ty = ty' then subtrm
   193          if ty = ty' then subtrm
   190          else mk_babs $ (mk_resp $ mk_resp_arg lthy (ty, ty')) $ subtrm
   194          else mk_babs $ (mk_resp $ mk_resp_arg ctxt (ty, ty')) $ subtrm
   191        end
   195        end
   192 
   196 
   193   | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') =>
   197   | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') =>
   194        let
   198        let
   195          val subtrm = apply_subt (regularize_trm lthy) (t, t')
   199          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   196        in
   200        in
   197          if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm
   201          if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm
   198          else mk_ball $ (mk_resp $ mk_resp_arg lthy (qnt_typ ty, qnt_typ ty')) $ subtrm
   202          else mk_ball $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   199        end
   203        end
   200 
   204 
   201   | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') =>
   205   | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') =>
   202        let
   206        let
   203          val subtrm = apply_subt (regularize_trm lthy) (t, t')
   207          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   204        in
   208        in
   205          if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm
   209          if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm
   206          else mk_bex $ (mk_resp $ mk_resp_arg lthy (qnt_typ ty, qnt_typ ty')) $ subtrm
   210          else mk_bex $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   207        end
   211        end
   208 
   212 
   209   | (* equalities need to be replaced by appropriate equivalence relations *) 
   213   | (* equalities need to be replaced by appropriate equivalence relations *) 
   210     (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) =>
   214     (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) =>
   211          if ty = ty' then rtrm
   215          if ty = ty' then rtrm
   212          else mk_resp_arg lthy (domain_type ty, domain_type ty') 
   216          else mk_resp_arg ctxt (domain_type ty, domain_type ty') 
   213 
   217 
   214   | (* in this case we just check whether the given equivalence relation is correct *) 
   218   | (* in this case we just check whether the given equivalence relation is correct *) 
   215     (rel, Const (@{const_name "op ="}, ty')) =>
   219     (rel, Const (@{const_name "op ="}, ty')) =>
   216        let 
   220        let 
   217          val exc = LIFT_MATCH "regularise (relation mismatch)"
   221          val exc = LIFT_MATCH "regularise (relation mismatch)"
   218          val rel_ty = (fastype_of rel) handle TERM _ => raise exc 
   222          val rel_ty = (fastype_of rel) handle TERM _ => raise exc 
   219          val rel' = mk_resp_arg lthy (domain_type rel_ty, domain_type ty') 
   223          val rel' = mk_resp_arg ctxt (domain_type rel_ty, domain_type ty') 
   220        in 
   224        in 
   221          if rel' aconv rel then rtrm else raise exc
   225          if rel' aconv rel then rtrm else raise exc
   222        end  
   226        end  
   223 
   227 
   224   | (_, Const _) =>
   228   | (_, Const _) =>
   239            (* cu: if I also test the type, then something else breaks *)
   243            (* cu: if I also test the type, then something else breaks *)
   240        in
   244        in
   241          if same_name rtrm qtrm then rtrm
   245          if same_name rtrm qtrm then rtrm
   242          else 
   246          else 
   243            let 
   247            let 
   244              val thy = ProofContext.theory_of lthy
   248              val thy = ProofContext.theory_of ctxt
   245              val qtrm_str = Syntax.string_of_term lthy qtrm
   249              val qtrm_str = Syntax.string_of_term ctxt qtrm
   246              val exc1 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " not found)")
   250              val exc1 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " not found)")
   247              val exc2 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " mismatch)")
   251              val exc2 = LIFT_MATCH ("regularize (constant " ^ qtrm_str ^ " mismatch)")
   248              val rtrm' = (#rconst (qconsts_lookup thy qtrm)) handle NotFound => raise exc1
   252              val rtrm' = (#rconst (qconsts_lookup thy qtrm)) handle NotFound => raise exc1
   249            in 
   253            in 
   250              if Pattern.matches thy (rtrm', rtrm) 
   254              if Pattern.matches thy (rtrm', rtrm) 
   251              then rtrm else raise exc2
   255              then rtrm else raise exc2
   252            end
   256            end
   253        end 
   257        end 
   254 
   258 
   255   | (t1 $ t2, t1' $ t2') =>
   259   | (t1 $ t2, t1' $ t2') =>
   256        (regularize_trm lthy (t1, t1')) $ (regularize_trm lthy (t2, t2'))
   260        (regularize_trm ctxt (t1, t1')) $ (regularize_trm ctxt (t2, t2'))
   257 
   261 
   258   | (Bound i, Bound i') =>
   262   | (Bound i, Bound i') =>
   259        if i = i' then rtrm 
   263        if i = i' then rtrm 
   260        else raise (LIFT_MATCH "regularize (bounds mismatch)")
   264        else raise (LIFT_MATCH "regularize (bounds mismatch)")
   261 
   265 
   262   | _ =>
   266   | _ =>
   263        let 
   267        let 
   264          val rtrm_str = Syntax.string_of_term lthy rtrm
   268          val rtrm_str = Syntax.string_of_term ctxt rtrm
   265          val qtrm_str = Syntax.string_of_term lthy qtrm
   269          val qtrm_str = Syntax.string_of_term ctxt qtrm
   266        in
   270        in
   267          raise (LIFT_MATCH ("regularize failed (default: " ^ rtrm_str ^ "," ^ qtrm_str ^ ")"))
   271          raise (LIFT_MATCH ("regularize failed (default: " ^ rtrm_str ^ "," ^ qtrm_str ^ ")"))
   268        end
   272        end
   269 
   273 
   270 fun regularize_trm_chk lthy (rtrm, qtrm) =
   274 fun regularize_trm_chk ctxt (rtrm, qtrm) =
   271   regularize_trm lthy (rtrm, qtrm) 
   275   regularize_trm ctxt (rtrm, qtrm) 
   272   |> Syntax.check_term lthy
   276   |> Syntax.check_term ctxt
   273 
   277 
   274 (*
   278 (*
   275 Injection of Rep/Abs means:
   279 Injection of Rep/Abs means:
   276 
   280 
   277   For abstractions
   281   For abstractions
   297   * We put aRep/Abs around it if the type needs lifting.
   301   * We put aRep/Abs around it if the type needs lifting.
   298 
   302 
   299   Vars case cannot occur.
   303   Vars case cannot occur.
   300 *)
   304 *)
   301 
   305 
   302 fun mk_repabs lthy (T, T') trm = 
   306 fun mk_repabs ctxt (T, T') trm = 
   303   absrep_fun repF lthy (T, T') $ (absrep_fun absF lthy (T, T') $ trm)
   307   absrep_fun repF ctxt (T, T') $ (absrep_fun absF ctxt (T, T') $ trm)
   304 
   308 
   305 
   309 
   306 (* bound variables need to be treated properly,     *)
   310 (* bound variables need to be treated properly,     *)
   307 (* as the type of subterms needs to be calculated   *)
   311 (* as the type of subterms needs to be calculated   *)
   308 
   312 
   309 fun inj_repabs_trm lthy (rtrm, qtrm) =
   313 fun inj_repabs_trm ctxt (rtrm, qtrm) =
   310  case (rtrm, qtrm) of
   314  case (rtrm, qtrm) of
   311     (Const (@{const_name "Ball"}, T) $ r $ t, Const (@{const_name "All"}, _) $ t') =>
   315     (Const (@{const_name "Ball"}, T) $ r $ t, Const (@{const_name "All"}, _) $ t') =>
   312        Const (@{const_name "Ball"}, T) $ r $ (inj_repabs_trm lthy (t, t'))
   316        Const (@{const_name "Ball"}, T) $ r $ (inj_repabs_trm ctxt (t, t'))
   313 
   317 
   314   | (Const (@{const_name "Bex"}, T) $ r $ t, Const (@{const_name "Ex"}, _) $ t') =>
   318   | (Const (@{const_name "Bex"}, T) $ r $ t, Const (@{const_name "Ex"}, _) $ t') =>
   315        Const (@{const_name "Bex"}, T) $ r $ (inj_repabs_trm lthy (t, t'))
   319        Const (@{const_name "Bex"}, T) $ r $ (inj_repabs_trm ctxt (t, t'))
   316 
   320 
   317   | (Const (@{const_name "Babs"}, T) $ r $ t, t' as (Abs _)) =>
   321   | (Const (@{const_name "Babs"}, T) $ r $ t, t' as (Abs _)) =>
   318       let
   322       let
   319         val rty = fastype_of rtrm
   323         val rty = fastype_of rtrm
   320         val qty = fastype_of qtrm
   324         val qty = fastype_of qtrm
   321       in
   325       in
   322         mk_repabs lthy (rty, qty) (Const (@{const_name "Babs"}, T) $ r $ (inj_repabs_trm lthy (t, t')))
   326         mk_repabs ctxt (rty, qty) (Const (@{const_name "Babs"}, T) $ r $ (inj_repabs_trm ctxt (t, t')))
   323       end
   327       end
   324 
   328 
   325   | (Abs (x, T, t), Abs (x', T', t')) =>
   329   | (Abs (x, T, t), Abs (x', T', t')) =>
   326       let
   330       let
   327         val rty = fastype_of rtrm
   331         val rty = fastype_of rtrm
   328         val qty = fastype_of qtrm
   332         val qty = fastype_of qtrm
   329         val (y, s) = Term.dest_abs (x, T, t)
   333         val (y, s) = Term.dest_abs (x, T, t)
   330         val (_, s') = Term.dest_abs (x', T', t')
   334         val (_, s') = Term.dest_abs (x', T', t')
   331         val yvar = Free (y, T)
   335         val yvar = Free (y, T)
   332         val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s'))
   336         val result = Term.lambda_name (y, yvar) (inj_repabs_trm ctxt (s, s'))
   333       in
   337       in
   334         if rty = qty then result
   338         if rty = qty then result
   335         else mk_repabs lthy (rty, qty) result
   339         else mk_repabs ctxt (rty, qty) result
   336       end
   340       end
   337 
   341 
   338   | (t $ s, t' $ s') =>  
   342   | (t $ s, t' $ s') =>  
   339        (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s'))
   343        (inj_repabs_trm ctxt (t, t')) $ (inj_repabs_trm ctxt (s, s'))
   340 
   344 
   341   | (Free (_, T), Free (_, T')) => 
   345   | (Free (_, T), Free (_, T')) => 
   342         if T = T' then rtrm 
   346         if T = T' then rtrm 
   343         else mk_repabs lthy (T, T') rtrm
   347         else mk_repabs ctxt (T, T') rtrm
   344 
   348 
   345   | (_, Const (@{const_name "op ="}, _)) => rtrm
   349   | (_, Const (@{const_name "op ="}, _)) => rtrm
   346 
   350 
   347   | (_, Const (_, T')) =>
   351   | (_, Const (_, T')) =>
   348       let
   352       let
   349         val rty = fastype_of rtrm
   353         val rty = fastype_of rtrm
   350       in 
   354       in 
   351         if rty = T' then rtrm
   355         if rty = T' then rtrm
   352         else mk_repabs lthy (rty, T') rtrm
   356         else mk_repabs ctxt (rty, T') rtrm
   353       end   
   357       end   
   354   
   358   
   355   | _ => raise (LIFT_MATCH "injection (default)")
   359   | _ => raise (LIFT_MATCH "injection (default)")
   356 
   360 
   357 fun inj_repabs_trm_chk lthy (rtrm, qtrm) =
   361 fun inj_repabs_trm_chk ctxt (rtrm, qtrm) =
   358   inj_repabs_trm lthy (rtrm, qtrm) 
   362   inj_repabs_trm ctxt (rtrm, qtrm) 
   359   |> Syntax.check_term lthy
   363   |> Syntax.check_term ctxt
   360 
   364 
   361 end; (* structure *)
   365 end; (* structure *)
   362 
   366 
   363 
   367 
   364 
   368