coq-club AT inria.fr
Subject: The Coq mailing list
List archive
Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint"
Chronological Thread
- From: Dominique Larchey-Wendling <dominique.larchey-wendling AT loria.fr>
- To: coq-club <coq-club AT inria.fr>
- Subject: Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint"
- Date: Sat, 13 Jul 2019 12:10:42 +0200 (CEST)
Notice that it is much simpler to define your function
once you know that F t = t. But I suppose you are
interested in a general approach, not just implementing
the identity function in a cumbersome way ...
Best,
Dominique
PS: F is now called G below to avoid naming
conficts
-------------------------------------------------
Section shorter_when_semantics_is_know.
Let R (t1 t2 : tree) := exists n, t2 = cons n t1.
Let Rwf : well_founded R.
Proof.
intros t.
induction t as [ n | n t IHt ]; constructor; intros x (m & Hm).
+ discriminate.
+ inversion Hm; subst; trivial.
Qed.
Let G_full (t : tree) : { t' | t' = t }.
Proof.
generalize (Rwf t); revert t.
refine (fix G t Ht { struct Ht } :=
match t as t' return t = t' -> _ with
| node _ => fun _ => exist _ t _
| cons n t' => fun E =>
let (t1,H1) := G t' _ in
let (t2,H2) := G t1 _
in exist _ (cons n t2) _
end eq_refl).
1,4: subst; trivial.
all: apply (Acc_inv Ht); exists n; subst; trivial.
Defined.
Definition G t := proj1_sig (G_full t).
Fact G_spec t : G t = t.
Proof. apply (proj2_sig (G_full _)). Qed.
End shorter_when_semantics_is_know.
Extraction G.
Let R (t1 t2 : tree) := exists n, t2 = cons n t1.
Let Rwf : well_founded R.
Proof.
intros t.
induction t as [ n | n t IHt ]; constructor; intros x (m & Hm).
+ discriminate.
+ inversion Hm; subst; trivial.
Qed.
Let G_full (t : tree) : { t' | t' = t }.
Proof.
generalize (Rwf t); revert t.
refine (fix G t Ht { struct Ht } :=
match t as t' return t = t' -> _ with
| node _ => fun _ => exist _ t _
| cons n t' => fun E =>
let (t1,H1) := G t' _ in
let (t2,H2) := G t1 _
in exist _ (cons n t2) _
end eq_refl).
1,4: subst; trivial.
all: apply (Acc_inv Ht); exists n; subst; trivial.
Defined.
Definition G t := proj1_sig (G_full t).
Fact G_spec t : G t = t.
Proof. apply (proj2_sig (G_full _)). Qed.
End shorter_when_semantics_is_know.
Extraction G.
De: "Dominique Larchey-Wendling" <dominique.larchey-wendling AT loria.fr>
À: "coq-club" <coq-club AT inria.fr>
Envoyé: Samedi 13 Juillet 2019 10:03:59
Objet: Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint"
Hi Morgane,From our work with JF Monin,here is what you can do on your particular nested algorithm ...I let you with the proof that your function is total ...Best,Dominique-----------------------------------------------------------------Require Extraction Setoid.
Set Implicit Arguments.
Section nested_on_trees.
Inductive tree : Type :=
| node : nat -> tree
| cons : nat -> tree -> tree.
Inductive gF : tree -> tree -> Prop :=
| in_gF0 : forall n, gF (node n) (node n)
| in_gF1 : forall n t1 t2 t3, gF t1 t2 -> gF t2 t3 -> gF (cons n t1) (cons n t3).
Fact gF_fun s t1 t2 : gF s t1 -> gF s t2 -> t1 = t2.
Proof.
intros H1 H2; revert H1 t2 H2.
induction 1 as [ n | n t1 t2 t3 H1 IH1 H2 IH2 ].
+ inversion 1; auto.
+ inversion 1; auto.
apply IH1 in H4; subst.
apply IH2 in H6; subst; auto.
Qed.
Unset Elimination Schemes.
Inductive dF : tree -> Prop :=
| in_dF0 : forall n, dF (node n)
| in_dF1 : forall n t1, dF t1 -> (forall t2, gF t1 t2 -> dF t2) -> dF (cons n t1).
Set Elimination Schemes.
Section F.
Let F_full : forall s, dF s -> sig (gF s).
Proof.
refine (fix loop s Hs { struct Hs } :=
match s as t return s = t -> sig (gF t) with
| node n => fun E => exist _ s _
| cons n t => fun E =>
let (t1,H1) := loop t _ in
let (t2,H2) := loop t1 _ in
exist _ (cons n t2) _
end eq_refl).
+ subst; constructor.
+ subst; inversion Hs; trivial.
+ subst; inversion Hs; apply H3; trivial.
+ constructor 2 with t1; trivial.
Qed.
Definition F s Hs := proj1_sig (@F_full s Hs).
Fact F_spec s Hs : gF s (@F s Hs).
Proof. apply (proj2_sig _). Qed.
End F.
Arguments F : clear implicits.
Fact dF0 n : dF (node n).
Proof. apply in_dF0. Qed.
Fact dF1 n t (Ht : dF t) : dF (F t Ht) -> dF (cons n t).
Proof.
intros H1; constructor 2; auto.
intros s Hs.
rewrite (gF_fun Hs (F_spec Ht)); trivial.
Qed.
Section dF_ind.
Variable P : forall t, dF t -> Prop.
Hypothesis HP0 : forall t H1 H2, @P t H1 -> @P t H2.
Hypothesis HP1 : forall n, P (dF0 n).
Hypothesis HP2 : forall n t1 H1 (_ : P H1) H2 (_ : P H2), P (@dF1 n t1 H1 H2).
Fixpoint dF_ind t Ht { struct Ht } : @P t Ht.
Proof.
destruct Ht as [ n | n t1 H1 H2 ].
+ apply HP0 with (1 := HP1 _).
+ apply HP0 with (1 := @HP2 n t1 _ (dF_ind _ H1) _ (dF_ind _ (H2 _ (F_spec H1)))).
Qed.
End dF_ind.
Fact F_fix0 n : F _ (dF0 n) = node n.
Proof.
apply gF_fun with (node n).
+ apply F_spec.
+ constructor.
Qed.
Fact F_fix1 n t1 H1 H2 : F _ (@dF1 n t1 H1 H2) = cons n (F _ H2).
Proof.
apply gF_fun with (cons n t1).
+ apply F_spec.
+ constructor 2 with (F _ H1); apply F_spec.
Qed.
Fact F_pirr t H1 H2 : F t H1 = F t H2.
Proof.
apply gF_fun with t; apply F_spec.
Qed.
(** Now you can study your function and show that it is total *)
Fact dF_total t : dF t.
Proof.
Admitted.
Definition F' t := F _ (dF_total t).
Fact F'_fix0 n : F' (node n) = node n.
Proof.
rewrite <- (F_fix0 n) at 2.
apply F_pirr.
Qed.
Fact F'_fix1 n t : F' (cons n t) = cons n (F' (F' t)).
Proof.
unfold F' at 2 3.
rewrite <- F_fix1.
apply F_pirr.
Qed.
End nested_on_trees.
Extraction F.De: "Morgan Sinclaire" <morgansinclaire AT boisestate.edu>
À: "coq-club" <coq-club AT inria.fr>
Envoyé: Jeudi 11 Juillet 2019 23:46:51
Objet: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint"Summary: I've received the error message "Only structural decreasing is supported for a non-Program Fixpoint", I have little clue what it means, and googling this message turned up no actual results. In particular I don't get what it means exactly by "structural decreasing" and "non-Program".~~~I have defined a Type called "ptree", which is an infinitary tree with a certain complicated structure, and I'm defining a function (which I'll just call F) that takes in a (P : ptree) as well as some simpler inputs, and returns a ptree. Abstracting away some other details, the definitions look roughly like this:Inductive ptree : Type :=
| node : nat -> ptree
| cons : nat -> ptree -> ptree
[...]
.Fixpoint F (P : ptree) [...] : ptree :=
match P with
| node n => P
| cons n P' => cons n (F (F P'))
[...]
end.Now, when I define F like this, I get the familiar "Cannot guess decreasing argument of fix" because of the double application of F. If I change "F (F P')" to "F P'" then the issue goes away, so on some level Coq recognizes that P gets simpler at each stage. However, when I try to tell Coq this by changing the first line to:Fixpoint F (P : ptree) [...] {measure P} : ptree :=Then I instead get the error message:Only structural decreasing is supported for a non-Program FixpointAnd I don't understand what this means, or how to tell Coq to recognize that P is simplifying, just like in the case where we have the single application F P' instead.(I believe I know of a way to avoid this double application of F in my situation, but that workaround is tedious, and besides I'm quite interested in understanding what's going on here).
- [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint", Morgan Sinclaire, 07/11/2019
- Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint", Christian Doczkal, 07/12/2019
- Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint", Dominique Larchey-Wendling, 07/13/2019
- Re: [Coq-Club] Error: "Only structural decreasing is supported for a non-Program Fixpoint", Dominique Larchey-Wendling, 07/13/2019
Archive powered by MHonArc 2.6.18.