-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Hi, I made recently an experiment of using parametricity techniques in Coq to automatically generate a Boolean equality associated to an inductive type as an alternative to the ad hoc algorithm currently in use.
It worked surprisingly well (see rocq-prover/rocq#15527) but I stumbled too on the fix
typing issue, that is on the question of proving that F (fix F)
is convertible to fix F
. I may have a solution working sometimes and reminiscent of the trick used for nice fixpoints in paramcoq. The trick is to use a "match"-expansion: for x
an inhabitant of the inductive type and assuming the type has constructor C
, we can translate fix f x := F f x
as
fix f_R x x' x_R :=
match x_R with
| C_R y y' y_R => F_R (fix f x := F f x) (fix f x := F f x) f_R (C y) (C y') (C_R y y' y_R)
end
what forces the reduction of (fix f x := F f x) y
inside F_R
into F f y
, because y
is now a constructor able to trigger the reduction.
I don't know yet the exact extent of the trick. It seems to require further match-expansions in F_R
if there are other match
in it.
Here is an example for the case of Boolean equality:
Fixpoint f n := (nat * match n with 0 => nat | S n => f n end)%type.
Require Import Bool.
Fail Fixpoint f_beq n : f n -> f n -> bool :=
fun '(a1,a2) '(b1,b2) => Nat.eqb a1 b1 &&
match n return f n -> f n -> bool with
| 0 => Nat.eqb a2 b2
| S n => f_beq a2 b2
end.
Fixpoint f_beq n : f n -> f n -> bool :=
match n return f n -> f n -> bool with
| 0 => fun '(a1,a2) '(b1,b2) => Nat.eqb a1 b1 && Nat.eqb a2 b2
| S n => fun '(a1,a2) '(b1,b2) => Nat.eqb a1 b1 && f_beq n a2 b2
end.
PS: Long time ago, @mlasson mentioned to me a problem with typing fixpoints in CIC but I have to confess that I don't remember if it was about adjusting the types in the recursive call or about the issue with constraints over indices in fixpoints, or maybe about both. So, maybe this was related.