Open adelaett opened 1 year ago
Hello, thanks for reporting the bug. On the last release
From elpi.apps Require Import derive.std.
Set Uniform Inductive Parameters.
Definition annotation (T: Type) := T.
Inductive term :=
| Dummy (x: bool)
| Lam (t: annotation term).
#[verbose,recursive,only(induction)] derive term.
shows
Error: derive.induction generates illtyped term: Illegal application:
The term "His_Lam" of type
"forall t : annotation term, is_annotation term P t -> P (Lam t)"
cannot be applied to the terms
"t" : "annotation term"
"Pt" : "is_annotation term is_term t"
The 2nd term has type "is_annotation term is_term t"
which should be coercible to "is_annotation term P t".
showing that induction generates a bad term, namely
fun (P : term -> Type) (His_Dummy : forall x : bool, is_bool x -> P (Dummy x))
(His_Lam : forall t : annotation term, is_annotation term P t -> P (Lam t))
=>
fix IH (s1 : term) (x : is_term s1) {struct x} : P s1 :=
match x in (is_term s2) return (P s2) with
| is_Dummy x0 Px => His_Dummy x0 Px
| is_Lam t Pt => His_Lam t Pt
end
which lacks a call to IH
in His_Lam t (IH t Pt)
I guess.
I'll need a few more days to find the time to tackle this one.
@gares ping :smile:
For some reason, we don't generate the functoriality property of definitions. If I amend that manually:
From elpi.apps Require Import derive.std.
Set Uniform Inductive Parameters.
Definition annotation (T: Type) := T.
#[verbose] derive annotation.
Definition is_annotation_functor T P Q :
(forall x:T, P x -> Q x) ->
forall x, is_annotation T P x -> is_annotation T Q x. trivial. Defined.
Elpi Accumulate derive lp:{{
param1-functor-db {{ is_annotation lp:T lp:P }} {{ is_annotation lp:T lp:Q }}
{{ is_annotation_functor lp:T lp:P lp:Q lp:H }} :-
param1-functor-db P Q H.
}}.
Inductive term :=
| Dummy (x: bool)
| Lam (t: annotation term).
#[verbose,recursive,only(induction)] derive term.
Print term_induction.
gives:
term_induction =
fun (P : term -> Type)
(His_Dummy : forall x : bool, is_bool x -> P (Dummy x))
(His_Lam : forall t : annotation term, is_annotation term P t -> P (Lam t))
=>
fix IH (s1 : term) (x : is_term s1) {struct x} : P s1 :=
match x in (is_term s2) return (P s2) with
| is_Dummy x0 Px => His_Dummy x0 Px
| is_Lam t Pt => His_Lam t (is_annotation_functor term is_term P IH t Pt)
end
: forall P : term -> Type,
(forall x : bool, is_bool x -> P (Dummy x)) ->
(forall t : annotation term, is_annotation term P t -> P (Lam t)) ->
forall s1 : term, is_term s1 -> P s1
The question is when this property holds and how to prove it systematically. CC @CohenCyril
~I think the answer is always on ground terms without axioms and I think I know how to implement it.~
Actually that's not true, I suspect not all param1 are going to be functorial. Take foo T := T -> T
for example.
We have is_foo T P := fun f : T -> T => forall x, P x -> P (f x)
and
unless I'm mistaken we don't have that (forall x, P x -> Q x) -> forall f, is_foo T P f -> is_foo T Q f
but only (forall x, P x <-> Q x) -> forall f, is_foo T P f -> is_foo T Q f
So it's functorial but for a different source category... :confused: but it looks too strong for your use case...
Yes, had the impressions that the position in which the parameter occurs makes it provable or not.
For "containers" the property is true as long as the parameter is positive (I mean at the left of ->
as in cons : A -> list A -> list A
, or used as another parameter). I don't know how this concept transports to definitions.
Actually we studied that with Enzo and Assia. In our upcoming paper we show how the shape of the term you have influences how strong hypotheses must be. CC @ecranceMERCE @amahboubi
OK, then I'll assign you the bug ;-)
And indeed it is essentially tied to positivity.
ocaml version: 4.14.0 Coq version : 8.16.1 coq-elpi version: 1.15.6 I'm trying to synthesize induction principles for terms builds using Autosubst using coq-elpi's derive. Here is a minimal example with the same issues:
Here is the induction principle that Coq generates
However, elpi's derive fails because of the annotation. Here is what I've tried:
Is there is a way to either:
Trace for Elpi derive annotation:
Trace for
Elpi derive.param1 term.
Looking forward to use your library