Quot/quotient_term.ML
changeset 795 a28f805df355
parent 792 a31cf260eeb3
child 796 64f9c76f70c7
equal deleted inserted replaced
794:f0a78fda343f 795:a28f805df355
     5    datatype flag = absF | repF
     5    datatype flag = absF | repF
     6    
     6    
     7    val absrep_fun: flag -> Proof.context -> (typ * typ) -> term
     7    val absrep_fun: flag -> Proof.context -> (typ * typ) -> term
     8    val absrep_fun_chk: flag -> Proof.context -> (typ * typ) -> term
     8    val absrep_fun_chk: flag -> Proof.context -> (typ * typ) -> term
     9 
     9 
       
    10    val equiv_relation: Proof.context -> (typ * typ) -> term
       
    11    val equiv_relation_chk: Proof.context -> (typ * typ) -> term
       
    12 
    10    val regularize_trm: Proof.context -> (term * term) -> term
    13    val regularize_trm: Proof.context -> (term * term) -> term
    11    val regularize_trm_chk: Proof.context -> (term * term) -> term
    14    val regularize_trm_chk: Proof.context -> (term * term) -> term
    12    
    15    
    13    val inj_repabs_trm: Proof.context -> (term * term) -> term
    16    val inj_repabs_trm: Proof.context -> (term * term) -> term
    14    val inj_repabs_trm_chk: Proof.context -> (term * term) -> term
    17    val inj_repabs_trm_chk: Proof.context -> (term * term) -> term
    55 end
    58 end
    56 
    59 
    57 (* produces an aggregate map function for the       *)
    60 (* produces an aggregate map function for the       *)
    58 (* rty-part of a quotient definition; abstracts     *)
    61 (* rty-part of a quotient definition; abstracts     *)
    59 (* over all variables listed in vs (these variables *)
    62 (* over all variables listed in vs (these variables *)
    60 (* correspond to the type variables in rty          *)        
    63 (* correspond to the type variables in rty)         *)        
    61 fun mk_mapfun ctxt vs ty =
    64 fun mk_mapfun ctxt vs ty =
    62 let
    65 let
    63   val vs' = map (mk_Free) vs
    66   val vs' = map (mk_Free) vs
    64 
    67 
    65   fun mk_mapfun_aux ty =
    68   fun mk_mapfun_aux ty =
    81   val qdata = (quotdata_lookup thy s) handle NotFound => raise exc
    84   val qdata = (quotdata_lookup thy s) handle NotFound => raise exc
    82 in
    85 in
    83   (#rtyp qdata, #qtyp qdata)
    86   (#rtyp qdata, #qtyp qdata)
    84 end
    87 end
    85 
    88 
    86 (* receives two type-environments and looks *)
    89 (* takes two type-environments and looks    *)
    87 (* up in both of them the variable v        *)
    90 (* up in both of them the variable v, which *)
       
    91 (* must be listed in the environment        *)
    88 fun double_lookup rtyenv qtyenv v =
    92 fun double_lookup rtyenv qtyenv v =
    89 let
    93 let
    90   val v' = fst (dest_TVar v)
    94   val v' = fst (dest_TVar v)
    91 in
    95 in
    92   (snd (the (Vartab.lookup rtyenv v')), snd (the (Vartab.lookup qtyenv v')))
    96   (snd (the (Vartab.lookup rtyenv v')), snd (the (Vartab.lookup qtyenv v')))
   101   case flag of
   105   case flag of
   102     absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT)
   106     absF => Const (Sign.full_bname thy ("abs_" ^ qty_name), dummyT)
   103   | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT)
   107   | repF => Const (Sign.full_bname thy ("rep_" ^ qty_name), dummyT)
   104 end
   108 end
   105 
   109 
   106 (* produces the aggregate absrep function                          *)
   110 fun absrep_match_err ctxt ty_pat ty =
       
   111 let
       
   112   val ty_pat_str = Syntax.string_of_typ ctxt ty_pat
       
   113   val ty_str = Syntax.string_of_typ ctxt ty 
       
   114 in
       
   115   raise LIFT_MATCH (space_implode " " 
       
   116     ["absrep_fun (Types ", quote ty_pat_str, "and", quote ty_str, " do not match.)"])
       
   117 end
       
   118 
       
   119 (* produces an aggregate absrep function                           *)
   107 (*                                                                 *)
   120 (*                                                                 *)
   108 (* - In case of function types and TFrees, we recurse, taking in   *) 
   121 (* - In case of function types and TFrees, we recurse, taking in   *) 
   109 (*   the first case the polarity change into account.              *)
   122 (*   the first case the polarity change into account.              *)
   110 (*                                                                 *)
   123 (*                                                                 *)
   111 (* - If the type constructors are equal, we recurse for the        *)
   124 (* - If the type constructors are equal, we recurse for the        *)
   155              list_comb (get_mapfun ctxt s, args)
   168              list_comb (get_mapfun ctxt s, args)
   156            end
   169            end
   157         else
   170         else
   158            let
   171            let
   159              val thy = ProofContext.theory_of ctxt
   172              val thy = ProofContext.theory_of ctxt
   160              val exc = (LIFT_MATCH "absrep_fun (Types do not match.)")
       
   161              val (rty_pat, qty_pat as Type (_, vs)) = get_rty_qty ctxt s'
   173              val (rty_pat, qty_pat as Type (_, vs)) = get_rty_qty ctxt s'
   162              val (rtyenv, qtyenv) = 
   174              val rtyenv = Sign.typ_match thy (rty_pat, rty) Vartab.empty
   163                      (Sign.typ_match thy (rty_pat, rty) Vartab.empty,
   175                           handle MATCH_TYPE => absrep_match_err ctxt rty_pat rty
   164                       Sign.typ_match thy (qty_pat, qty) Vartab.empty)
   176              val qtyenv = Sign.typ_match thy (qty_pat, qty) Vartab.empty
   165                       handle MATCH_TYPE => raise exc
   177                           handle MATCH_TYPE => absrep_match_err ctxt qty_pat qty 
   166              val args_aux = map (double_lookup rtyenv qtyenv) vs            
   178              val args_aux = map (double_lookup rtyenv qtyenv) vs            
   167              val args = map (absrep_fun flag ctxt) args_aux
   179              val args = map (absrep_fun flag ctxt) args_aux
   168              val map_fun = mk_mapfun ctxt vs rty_pat       
   180              val map_fun = mk_mapfun ctxt vs rty_pat       
   169              val result = list_comb (map_fun, args) 
   181              val result = list_comb (map_fun, args) 
   170            in
   182            in
   180 fun absrep_fun_chk flag ctxt (rty, qty) =
   192 fun absrep_fun_chk flag ctxt (rty, qty) =
   181   absrep_fun flag ctxt (rty, qty)
   193   absrep_fun flag ctxt (rty, qty)
   182   |> Syntax.check_term ctxt
   194   |> Syntax.check_term ctxt
   183 
   195 
   184 
   196 
   185 (* Regularizing an rtrm means:
   197 (**********************************)
   186  
   198 (* Aggregate Equivalence Relation *)
   187  - Quantifiers over types that need lifting are replaced 
   199 (**********************************)
   188    by bounded quantifiers, for example:
       
   189 
       
   190       All P  ----> All (Respects R) P
       
   191 
       
   192    where the aggregate relation R is given by the rty and qty;
       
   193  
       
   194  - Abstractions over types that need lifting are replaced
       
   195    by bounded abstractions, for example:
       
   196       
       
   197       %x. P  ----> Ball (Respects R) %x. P
       
   198 
       
   199  - Equalities over types that need lifting are replaced by
       
   200    corresponding equivalence relations, for example:
       
   201 
       
   202       A = B  ----> R A B
       
   203 
       
   204    or 
       
   205 
       
   206       A = B  ----> (R ===> R) A B
       
   207  
       
   208    for more complicated types of A and B
       
   209 *)
       
   210 
   200 
   211 (* instantiates TVars so that the term is of type ty *)
   201 (* instantiates TVars so that the term is of type ty *)
   212 fun force_typ ctxt trm ty =
   202 fun force_typ ctxt trm ty =
   213 let
   203 let
   214   val thy = ProofContext.theory_of ctxt 
   204   val thy = ProofContext.theory_of ctxt 
   237 
   227 
   238 (* builds the aggregate equivalence relation *)
   228 (* builds the aggregate equivalence relation *)
   239 (* that will be the argument of Respects     *)
   229 (* that will be the argument of Respects     *)
   240 
   230 
   241 (* FIXME: check that the types correspond to each other? *)
   231 (* FIXME: check that the types correspond to each other? *)
   242 fun mk_resp_arg ctxt (rty, qty) =
   232 fun equiv_relation ctxt (rty, qty) =
   243   if rty = qty
   233   if rty = qty
   244   then HOLogic.eq_const rty
   234   then HOLogic.eq_const rty
   245   else
   235   else
   246     case (rty, qty) of
   236     case (rty, qty) of
   247       (Type (s, tys), Type (s', tys')) =>
   237       (Type (s, tys), Type (s', tys')) =>
   248        if s = s' 
   238        if s = s' 
   249        then 
   239        then 
   250          let
   240          let
   251            val args = map (mk_resp_arg ctxt) (tys ~~ tys')
   241            val args = map (equiv_relation ctxt) (tys ~~ tys')
   252          in
   242          in
   253            list_comb (get_relmap ctxt s, args) 
   243            list_comb (get_relmap ctxt s, args) 
   254          end  
   244          end  
   255        else 
   245        else 
   256          let
   246          let
   257            val eqv_rel = get_equiv_rel ctxt s'
   247            val eqv_rel = get_equiv_rel ctxt s'
   258          in
   248          in
   259            force_typ ctxt eqv_rel ([rty, rty] ---> @{typ bool})
   249            force_typ ctxt eqv_rel ([rty, rty] ---> @{typ bool})
   260          end
   250          end
   261       | _ => HOLogic.eq_const rty
   251       | _ => HOLogic.eq_const rty
       
   252 
       
   253 fun equiv_relation_chk ctxt (rty, qty) =
       
   254   equiv_relation ctxt (rty, qty)
       
   255   |> Syntax.check_term ctxt
       
   256 
       
   257 
       
   258 (******************)
       
   259 (* Regularization *)
       
   260 (******************)
       
   261 
       
   262 (* Regularizing an rtrm means:
       
   263  
       
   264  - Quantifiers over types that need lifting are replaced 
       
   265    by bounded quantifiers, for example:
       
   266 
       
   267       All P  ----> All (Respects R) P
       
   268 
       
   269    where the aggregate relation R is given by the rty and qty;
       
   270  
       
   271  - Abstractions over types that need lifting are replaced
       
   272    by bounded abstractions, for example:
       
   273       
       
   274       %x. P  ----> Ball (Respects R) %x. P
       
   275 
       
   276  - Equalities over types that need lifting are replaced by
       
   277    corresponding equivalence relations, for example:
       
   278 
       
   279       A = B  ----> R A B
       
   280 
       
   281    or 
       
   282 
       
   283       A = B  ----> (R ===> R) A B
       
   284  
       
   285    for more complicated types of A and B
       
   286 *)
       
   287 
   262             
   288             
   263 val mk_babs = Const (@{const_name Babs}, dummyT)
   289 val mk_babs = Const (@{const_name Babs}, dummyT)
   264 val mk_ball = Const (@{const_name Ball}, dummyT)
   290 val mk_ball = Const (@{const_name Ball}, dummyT)
   265 val mk_bex  = Const (@{const_name Bex}, dummyT)
   291 val mk_bex  = Const (@{const_name Bex}, dummyT)
   266 val mk_resp = Const (@{const_name Respects}, dummyT)
   292 val mk_resp = Const (@{const_name Respects}, dummyT)
   290     (Abs (x, ty, t), Abs (_, ty', t')) =>
   316     (Abs (x, ty, t), Abs (_, ty', t')) =>
   291        let
   317        let
   292          val subtrm = Abs(x, ty, regularize_trm ctxt (t, t'))
   318          val subtrm = Abs(x, ty, regularize_trm ctxt (t, t'))
   293        in
   319        in
   294          if ty = ty' then subtrm
   320          if ty = ty' then subtrm
   295          else mk_babs $ (mk_resp $ mk_resp_arg ctxt (ty, ty')) $ subtrm
   321          else mk_babs $ (mk_resp $ equiv_relation ctxt (ty, ty')) $ subtrm
   296        end
   322        end
   297 
   323 
   298   | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') =>
   324   | (Const (@{const_name "All"}, ty) $ t, Const (@{const_name "All"}, ty') $ t') =>
   299        let
   325        let
   300          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   326          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   301        in
   327        in
   302          if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm
   328          if ty = ty' then Const (@{const_name "All"}, ty) $ subtrm
   303          else mk_ball $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   329          else mk_ball $ (mk_resp $ equiv_relation ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   304        end
   330        end
   305 
   331 
   306   | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') =>
   332   | (Const (@{const_name "Ex"}, ty) $ t, Const (@{const_name "Ex"}, ty') $ t') =>
   307        let
   333        let
   308          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   334          val subtrm = apply_subt (regularize_trm ctxt) (t, t')
   309        in
   335        in
   310          if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm
   336          if ty = ty' then Const (@{const_name "Ex"}, ty) $ subtrm
   311          else mk_bex $ (mk_resp $ mk_resp_arg ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   337          else mk_bex $ (mk_resp $ equiv_relation ctxt (qnt_typ ty, qnt_typ ty')) $ subtrm
   312        end
   338        end
   313 
   339 
   314   | (* equalities need to be replaced by appropriate equivalence relations *) 
   340   | (* equalities need to be replaced by appropriate equivalence relations *) 
   315     (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) =>
   341     (Const (@{const_name "op ="}, ty), Const (@{const_name "op ="}, ty')) =>
   316          if ty = ty' then rtrm
   342          if ty = ty' then rtrm
   317          else mk_resp_arg ctxt (domain_type ty, domain_type ty') 
   343          else equiv_relation ctxt (domain_type ty, domain_type ty') 
   318 
   344 
   319   | (* in this case we just check whether the given equivalence relation is correct *) 
   345   | (* in this case we just check whether the given equivalence relation is correct *) 
   320     (rel, Const (@{const_name "op ="}, ty')) =>
   346     (rel, Const (@{const_name "op ="}, ty')) =>
   321        let 
   347        let 
   322          val exc = LIFT_MATCH "regularise (relation mismatch)"
   348          val exc = LIFT_MATCH "regularise (relation mismatch)"
   323          val rel_ty = fastype_of rel
   349          val rel_ty = fastype_of rel
   324          val rel' = mk_resp_arg ctxt (domain_type rel_ty, domain_type ty') 
   350          val rel' = equiv_relation ctxt (domain_type rel_ty, domain_type ty') 
   325        in 
   351        in 
   326          if rel' aconv rel then rtrm else raise exc
   352          if rel' aconv rel then rtrm else raise exc
   327        end  
   353        end  
   328 
   354 
   329   | (_, Const _) =>
   355   | (_, Const _) =>
   374 
   400 
   375 fun regularize_trm_chk ctxt (rtrm, qtrm) =
   401 fun regularize_trm_chk ctxt (rtrm, qtrm) =
   376   regularize_trm ctxt (rtrm, qtrm) 
   402   regularize_trm ctxt (rtrm, qtrm) 
   377   |> Syntax.check_term ctxt
   403   |> Syntax.check_term ctxt
   378 
   404 
       
   405 (*********************)
       
   406 (* Rep/Abs Injection *)
       
   407 (*********************)
       
   408 
   379 (*
   409 (*
   380 Injection of Rep/Abs means:
   410 Injection of Rep/Abs means:
   381 
   411 
   382   For abstractions
   412   For abstractions
   383 :
   413 :