summaryrefslogtreecommitdiff
path: root/contrib/subtac/subtac_coercion.ml
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/subtac/subtac_coercion.ml')
-rw-r--r--contrib/subtac/subtac_coercion.ml101
1 files changed, 59 insertions, 42 deletions
diff --git a/contrib/subtac/subtac_coercion.ml b/contrib/subtac/subtac_coercion.ml
index 3613ec4f..c764443f 100644
--- a/contrib/subtac/subtac_coercion.ml
+++ b/contrib/subtac/subtac_coercion.ml
@@ -5,7 +5,7 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: subtac_coercion.ml 9563 2007-01-31 09:37:18Z msozeau $ *)
+(* $Id: subtac_coercion.ml 9976 2007-07-12 11:58:30Z msozeau $ *)
open Util
open Names
@@ -26,7 +26,6 @@ open Subtac_utils
open Coqlib
open Printer
open Subtac_errors
-open Context
open Eterm
open Pp
@@ -86,6 +85,13 @@ module Coercion = struct
let hnf env isevars c = whd_betadeltaiota env (evars_of !isevars) c
+ let lift_args n sign =
+ let rec liftrec k = function
+ | t::sign -> liftn n k t :: (liftrec (k-1) sign)
+ | [] -> []
+ in
+ liftrec (List.length sign) sign
+
let rec mu env isevars t =
let isevars = ref isevars in
let rec aux v =
@@ -113,15 +119,41 @@ module Coercion = struct
(* (try debug 1 (str "coerce_unify from " ++ (my_print_constr env x) ++ *)
(* str " to "++ my_print_constr env y) *)
(* with _ -> ()); *)
- try
- isevars := the_conv_x_leq env x y !isevars;
-(* (try debug 1 (str "Unified " ++ (my_print_constr env x) ++ *)
-(* str " and "++ my_print_constr env y); *)
-(* with _ -> ()); *)
- None
- with Reduction.NotConvertible -> coerce' env (hnf env isevars x) (hnf env isevars y)
+ let x = hnf env isevars x and y = hnf env isevars y in
+ try
+ isevars := the_conv_x_leq env x y !isevars;
+ (* (try debug 1 (str "Unified " ++ (my_print_constr env x) ++ *)
+ (* str " and "++ my_print_constr env y); *)
+ (* with _ -> ()); *)
+ None
+ with Reduction.NotConvertible -> coerce' env x y
and coerce' env x y : (Term.constr -> Term.constr) option =
let subco () = subset_coerce env isevars x y in
+ let rec coerce_application typ c c' l l' =
+ let len = Array.length l in
+ let rec aux tele typ i co =
+ if i < len then
+ let hdx = l.(i) and hdy = l'.(i) in
+ try isevars := the_conv_x_leq env hdx hdy !isevars;
+ let (n, eqT, restT) = destProd typ in
+ aux (hdx :: tele) (subst1 hdy restT) (succ i) co
+ with Reduction.NotConvertible ->
+ let (n, eqT, restT) = destProd typ in
+ let restargs = lift_args 1
+ (List.rev (Array.to_list (Array.sub l (succ i) (len - (succ i)))))
+ in
+ let args = List.rev (restargs @ mkRel 1 :: lift_args 1 tele) in
+ let pred = mkLambda (n, eqT, applistc (lift 1 c) args) in
+ let eq = mkApp (Lazy.force eq_ind, [| eqT; hdx; hdy |]) in
+(* let jmeq = mkApp (Lazy.force jmeq_ind, [| eqT; hdx; eqT; hdy |]) in *)
+ let evar = make_existential dummy_loc env isevars eq in
+ let eq_app x = mkApp (Lazy.force eq_rect,
+ [| eqT; hdx; pred; x; hdy; evar|]) in
+ trace (str"Inserting coercion at application");
+ aux (hdy :: tele) (subst1 hdy restT) (succ i) (fun x -> eq_app (co x))
+ else co
+ in aux [] typ 0 (fun x -> x)
+ in
(* (try debug 1 (str "coerce' from " ++ (my_print_constr env x) ++ *)
(* str " to "++ my_print_constr env y); *)
(* with _ -> ()); *)
@@ -214,40 +246,25 @@ module Coercion = struct
mkApp (prod.intro, [| a'; b'; x ; y |]))
end
else
- (* if len = 1 && len = Array.length l' && i = i' then *)
-(* let argx, argy = l.(0), l'.(0) in *)
-(* let indtyp = Inductiveops.type_of_inductive env i in *)
-(* let argname, argtype, _ = destProd indtyp in *)
-(* let eq = *)
-(* mkApp (Lazy.force eqind, [| argtype; argx; argy |]) *)
-(* in *)
-(* let pred = mkLambda (argname, argtype, *)
-(* mkApp (mkInd i, [| mkRel 1 |])) *)
-(* in *)
-(* let evar = make_existential dummy_loc env isevars eq in *)
-(* Some (fun x -> *)
-(* mkApp (Lazy.force eqrec, *)
-(* [| argtype; argx; pred; x; argy; evar |])) *)
-(* else *)subco ()
+ if i = i' && len = Array.length l' then
+ let evm = evars_of !isevars in
+ let typ = Typing.type_of env evm c in
+ (try subco ()
+ with NoSubtacCoercion ->
+
+(* if not (is_arity env evm typ) then *)
+ Some (coerce_application typ c c' l l'))
+(* else subco () *)
+ else
+ subco ()
| x, y when x = y ->
- let lam_type = Typing.type_of env (evars_of !isevars) c in
- let rec coerce typ i co =
- if i < Array.length l then
- let hdx = l.(i) and hdy = l'.(i) in
- let (n, eqT, restT) = destProd typ in
- let pred = mkLambda (n, eqT, mkApp (lift 1 c, [| mkRel 1 |])) in
- let eq = mkApp (Lazy.force eq_ind, [| eqT; hdx; hdy |]) in
- let evar = make_existential dummy_loc env isevars eq in
- let eq_app x = mkApp (Lazy.force eq_rect,
- [| eqT; hdx; pred; x; hdy; evar|])
- in
- coerce (subst1 hdy restT) (succ i) (fun x -> eq_app (co x))
- else co
- in
- if Array.length l = Array.length l' then (
- trace (str"Inserting coercion at application");
- Some (coerce lam_type 0 (fun x -> x))
- ) else subco ()
+ if Array.length l = Array.length l' then
+ let evm = evars_of !isevars in
+ let lam_type = Typing.type_of env evm c in
+(* if not (is_arity env evm lam_type) then ( *)
+ Some (coerce_application lam_type c c' l l')
+(* ) else subco () *)
+ else subco ()
| _ -> subco ())
| _, _ -> subco ()