coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.net>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Termination checker for structural recursion
- Date: Thu, 22 Aug 2019 18:23:28 +0200
- Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=gaetan.gilbert AT skyskimmer.net; spf=Pass smtp.mailfrom=gaetan.gilbert AT skyskimmer.net; spf=None smtp.helo=postmaster AT relay7-d.mail.gandi.net
- Ironport-phdr: 9a23:2STgxB9h06peBP9uRHKM819IXTAuvvDOBiVQ1KB30eIcTK2v8tzYMVDF4r011RmVBN+dsq4awLeL+4nbGkU4qa6bt34DdJEeHzQksu4x2zIaPcieFEfgJ+TrZSFpVO5LVVti4m3peRMNQJW2aFLduGC94iAPERvjKwV1Ov71GonPhMiryuy+4ZLebxhWiDanfL9/IxS7oQrRu8QWnIBvNrs/xhzVr3VSZu9Y33loJVWdnxb94se/4ptu+DlOtvwi6sBNT7z0c7w3QrJEAjsmNXs15NDwuhnYUQSP/HocXX4InRdOHgPI8Qv1Xpb1siv9q+p9xCyXNtD4QLwoRTiv6bpgRRn1gykFKjE56nnahNFugqJVoByvpBJxzIDbb46XKPVwcbjQfc8ZSGdbQspdSyJMD4G6YoASD+QBJ+FYr4zlqlUPtxS5GRWsC/npyjBQh3H23Kk63P8/HgHcwAwrAtUDsHvOo9rrKKcdS+a1wLPHzTXCa/NZwiny6JLUch06uvGMXrJxcdHSyUkuEgPFi0ufqZb/MzOTyOsNr3GW4ux9XuyhjG4nrht+ojmpxso0i4nJgJgVylHe+iljzoY1P9u1Q1N4b968CJZcqTyWOolsTs4gX21kojs2x74ItJKhYiQG1IgrywbBZ/CafYWE+A/vWeaPLTtimX5oeayziwyv/UWgzOD3S9O630xQriVfl9nBrnAN2ALX6siAUvZ95Fmu2TKV2AHT6OxIOF07mbDeK5E7w74wkoAfsUvZES/whUr2jbWadkM69ei08+jnY7PmqYGAN4JslA3yL6Yjlta9DOgkKAQCQmuW9Oqm2LH94UH1XK1GjvgsnanYtJDaK94bpqm8AwJN3YYs8QiwDyu839Qeh3UHI1NFeBacgIf3IVHOPOv1Dey8g1WsizdrxPHGPrjkAprTNHjPirHhcqhh60JE0go80chf545ICrEGOP/8RkjxtMXBAhAlNwy03v3oBc5m1oIeXGKPGrWWPLnTsV+O/OIvIvODaJUbuDbneLAZ4KvlimZ8klsAd4Go24EWYTa2BKdIOUKcNFXlAcsIF1Alvw40Qfb2wAmNWDNPbnD0UKM47DwhFKq9DpbYRYGohbGbmiG2AssFNSh9FlmQHCKwJM2/UPAWZXfKe54zonk/TbGkDrQZ+1SrvQ7+xaBgK7OKqDYbpIng1d1w6veVkxwup2UtUpatllqVRmQxpVsmAj872Kcl/B5nx1OKwPc9j7pdHN1XofxAVAs7c5jR074iUoygakf6Zt6MDW2ebJC+GzhoEIAqwM4VYEd4Hti4yBbOw3jyDg==
See https://coq.inria.fr/distrib/current/refman/language/cic.html#fixpoint-definitions
>The main rules for being structurally smaller are the following.
>...
The termination checker reduces constants when needed, so it sees that False_ind is a match where all branches are smaller than lenp (since there are no branches ^^)
Gaëtan Gilbert
On 22/08/2019 17:56, Vincent Semeria wrote:
Dear Coq clubbers,
Consider this (silly) implementation of the subtraction of natural numbers :
Fixpoint subtract (p n : nat) (lenp : le n p) { struct lenp }
: { k : nat | n + k = p }.
Proof.
destruct (Nat.eq_dec n p) as [e|d].
- exists 0. subst p. rewrite Nat.add_0_r. reflexivity.
- destruct (subtract (pred p) n
(match lenp in (_ <= n0) return (n <> n0 -> n <= Init.Nat.pred n0) with
| le_n _ => fun H : n <> n => False_ind (n <= Init.Nat.pred n) (H eq_refl)
| le_S _ m H1 => fun _ : n <> S m => H1
end d)).
exists (S x). destruct p.
+ exfalso. inversion lenp. subst n. exact (d (eq_refl _)).
+ simpl in e. rewrite Nat.add_succ_r. apply f_equal. exact e.
Defined.
Is there a documentation somewhere explaining how the termination checker is happy with it ? The only doc I found is this
https://coq.inria.fr/distrib/current/refman/language/coq-library.html#index-19
and it only tells that the type well_founded will terminate on induction, not how it works.
In subtract above, the recursive call is eventually made on a structurally smaller piece of lenp, which is H1. But before getting H1, the second branch of the match has to beta-reduce (fun _ => H1) d. Does it only work with constant functions ?
Also, the first branch of the match doesn't provide any smaller piece of lenp. It is actually a dead branch, as shows False_ind. So the termination checker is right to forget it, because it will never be taken by computations. However I imagine that does require intelligence in the checker, and I don't think that it simply tests the string "False_ind".
Regards,
Vincent
- [Coq-Club] Termination checker for structural recursion, Vincent Semeria, 08/22/2019
- Re: [Coq-Club] Termination checker for structural recursion, Gaëtan Gilbert, 08/22/2019
Archive powered by MHonArc 2.6.18.