coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Jason Gross <jasongross9 AT gmail.com>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] how many type indexes for a particular type?
- Date: Wed, 20 Jul 2016 21:55:29 +0000
- Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=jasongross9 AT gmail.com; spf=Pass smtp.mailfrom=jasongross9 AT gmail.com; spf=None smtp.helo=postmaster AT mail-oi0-f50.google.com
- Ironport-phdr: 9a23:YMjnYBb6Lxv2jTl0UBAp7Pr/LSx+4OfEezUN459isYplN5qZpc+6bnLW6fgltlLVR4KTs6sC0LuO9f28EjRbqb+681k6OKRWUBEEjchE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i760zceF13FOBZvIaytQ8iJ3pzxirz5o8abSj4LrQL1Wal1IhSyoFeZnegtqqwmFJwMzADUqGBDYeVcyDAgD1uSmxHh+pX4p8Y7oGwD884mosVHSODxe7kyZb1eFjUvdW4vt+PxshyWbwKU4X1UfX8RiQEAVwrM9xb8UY32qTCrnuV40Siee8bxSOZnCnyZ8653RUqw2288PDkj/TSPhw==
Ltac strip_useless_binders term :=
lazymatch term with
| _ -> ?T => strip_useless_binders T
| fun _ => ?T => strip_useless_binders T
| _ => term
end.
Ltac count_prods term :=
lazymatch (eval hnf in term) with
| forall x : ?T, @?f x
=> let v := constr:(fun x : T => ltac:(let v := count_prods (f x) in exact v)) in
let v := strip_useless_binders v in
constr:(S v)
| _ => constr:(0)
end.
Ltac get_prods_of_type_of term :=
let T := type of term in
count_prods T.
Ltac get_type_after_case_count ty :=
let v := constr:(ltac:(let x := fresh in
evar (x : nat);
let xv := (eval cbv [x] in x) in
assert (ty -> True);
[ let term := fresh in
intro term; case term;
[ let G := match goal with |- ?G => G end in
let v := count_prods G in
unify xv v;
intros; exact I
| intros; exact I.. ]
| eexact xv ])) in
eval cbv zeta in v.
Ltac head term :=
match term with
| ?f _ => head f
| _ => term
end.
Ltac get_first_ctor ty :=
let v := constr:(ltac:(let x := fresh in
let T := fresh in
evar (T : Type);
evar (x : T); subst T;
let xv := (eval cbv [x] in x) in
assert (ty -> True);
[ let p := fresh in
intro p;
let H := fresh in
destruct p eqn:H;
[ let ty := match type of H with
| _ = ?RHS => RHS
end in
let ty := head ty in
unify xv ty;
intros; exact I
| intros; exact I.. ]
| eexact xv ])) in
eval cbv zeta in v.
Ltac get_parameter_count_of_ty ty :=
let first_ctor := get_first_ctor ty in
let total_args := get_prods_of_type_of first_ctor in
let non_parameter_args := get_type_after_case_count ty in
eval compute in (total_args - non_parameter_args).
Ltac under_type_binders term tac :=
let ty := type of term in
lazymatch eval hnf in ty with
| forall x : ?T, _
=> let x' := fresh x in
let v := constr:(fun x' : T => ltac:(let v := under_type_binders (term x') tac in eexact v)) in
strip_useless_binders v
| ?ty => let v := constr:(ltac:(tac term)) in
v
end.
Ltac get_parameter_count ty_family :=
let v := under_type_binders ty_family ltac:(fun ty => let v := get_parameter_count_of_ty ty in eexact v) in
v.
Inductive Foo : nat -> Set := foo(n : nat) : Foo n.
Inductive Bar(n : nat) : Set := bar.
Inductive eq' : forall {A}, A -> A -> Prop := eq_refl' A x : @eq' A x x.
Goal True.
let t := constr:(@Foo) in let v := get_parameter_count t in idtac t v. (* Foo 0 *)
let t := constr:(@Bar) in let v := get_parameter_count t in idtac t v. (* Bar 1 *)
let t := constr:(@Logic.eq) in let v := get_parameter_count t in idtac t v. (* @eq 2 *)
let t := constr:(@eq') in let v := get_parameter_count t in idtac t v. (* @eq' 0 *)
On Wed, Jul 20, 2016 at 2:30 PM Jonathan Leivent <jonikelee AT gmail.com> wrote:
On 07/20/2016 05:04 PM, Jonathan Leivent wrote:
>
>
> On 07/20/2016 04:45 PM, Jonathan Leivent wrote:
>>
>>
>> On 07/20/2016 04:37 PM, Jason Gross wrote:
>>> Here is a way to distinguish based on the results of typechecking:
>>> Inductive eq : forall {A}, A -> A -> Prop := eq_refl A x : @eq A x x.
>>> Inductive eq' {A} (x : A) : A -> Prop := eq_refl' : @eq' A x x.
>>> Check fun A x y (p : @eq A x y) => match p in (@eq A' x' y') with _
>>> => I
>>> end.
>>> Fail Check fun A x y (p : @eq' A x y) => match p in (@eq' A' x' y')
>>> with _
>>> => I end. (* Error: The parameters do not bind in patterns; they
>>> must be
>>> replaced by '_'. *)
>>>
>>> I wish you luck in making this work in general; it seems that the [in]
>>> clause does special name-resolution and ignores ltac-variables.
>>>
>>> Here's another way that may prove more fruitful:
>>>
>>> Goal forall A x y, @eq A x y -> True.
>>> intros ??? p.
>>> case p. (* forall A0 : Type, A0 -> True *)
>>> Abort.
>>> Goal forall A x y, @eq' A x y -> True.
>>> intros ??? p.
>>> case p. (* True *)
>>> Abort.
>>
>> Using case this way looks promising. So, the number of intros will
>> be the number of non-index parameter.
>> I'll try making a tactic that uses that...
>
> On second thought - that doesn't work. We're confusing ctor fields
> with indexes. Of course case will produce intros for the fields.
>
> -- Jonathan
This might work - based on the fact that case alters index fields in the
conclusion but not parameters. So, given an inductive type completely
parameterized by individual distinct hyps, casing an instance with
another matching instance in the conclusion will cause the conclusion's
copy to differ from the cased one by exactly just the indexes:
Inductive Foo(i :nat) : bool -> Set := foo(n:nat) : Foo i true.
Goal forall i b, Foo i b -> Foo i b -> True.
intros i b f.
case f. (*conclusion will have fields, then Foo i true -> True *)
-- Jonathan
>
>>
>> Thanks!
>>
>> -- Jonathan
>>
>>>
>>> On Wed, Jul 20, 2016 at 1:25 PM Jonathan Leivent <jonikelee AT gmail.com>
>>> wrote:
>>>
>>>> Is there any way accessible via Ltac that one can get the count of the
>>>> number of indexes for a particular inductive type? Not the total
>>>> number
>>>> of parameters - just the indexes.
>>>>
>>>> Examining the inductive type doesn't tell you which of that type's
>>>> args
>>>> are indexes or just parameters.
>>>>
>>>> Examining the constructors usually helps some, because the point where
>>>> the args of the constructors differ from each other or the args of the
>>>> type indicates that there are no more non-indexes after that point.
>>>> But, there may be indexes that don't vary. Hence, in:
>>>>
>>>> Inductive Foo : nat -> Set := foo(n : nat) : Foo n.
>>>>
>>>> Inductive Bar(n : nat) : Set := bar.
>>>>
>>>> Foo and Bar have the same type nat -> Set, and their constructors foo
>>>> and bar have similar type structure as well (modulo Foo/Bar). Yet, Foo
>>>> has a type index while Bar doesn't.
>>>>
>>>> -- Jonathan
>>>>
>>>>
>>>>
>>
>
- [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jason Gross, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jason Gross, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/21/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Emilio Jesús Gallego Arias, 07/21/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jason Gross, 07/21/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/22/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/21/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jason Gross, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jonathan Leivent, 07/20/2016
- Re: [Coq-Club] how many type indexes for a particular type?, Jason Gross, 07/20/2016
Archive powered by MHonArc 2.6.18.