Coercion in pairs - coq

Why do coercions not work inside pairs? In my project I have coercions from Foo to Bar, which works well if I have one Foo but want one Bar. But it does not work if I want a pair of Bars, but have a pair of Foos.
Inductive Foo := foo.
Inductive Bar := fromFoo of Foo.
Coercion fromFoo : Foo >-> Bar.
(* This works *)
Definition bar : Bar := foo.
(* This fails *)
Fail Definition bars : (Bar * Bar) := (foo,foo).
Why would Coq not insert the coercion here?

Related

Why can't Coq infer my coercion when applying arguments to coercible term?

I'm trying to write a coercion of a specific sigma type into a binary relation. The coercion works when using a coercible term as a function argument, but not when using the same term as a function.
Here is the code:
Definition relation A := A -> A -> Prop.
Definition is_serial {A} (R: relation A) := forall x, exists y, R x y.
Definition serial state := {R: relation state | is_serial R}.
Definition serial_to_relation A (s: serial A) : relation A := proj1_sig s.
Coercion serial_to_relation : serial >-> relation.
Parameter foo: serial nat.
Parameter bar: relation nat -> Prop.
(* Succeeds in coercing an argument. *)
Check (bar foo).
(* Fails to coerce when applying arguments to coercible term *)
Fail Check (foo 1 2).
Here's an executable version of the snippet: https://x80.org/collacoq/udutosoher.coq
Why does the second check fail? Did I make a mistake in my coercion definition? Or is this some limitation of coercion inference that I'm unaware of?
I think the problem in the last case is that Coq tries to infer a function type for foo and relation A is not literally a function type (only up to unfolding of the definition of relation).
If you add a coercion to Funclass (see the doc) as follows then the last test goes through
Definition serial_to_fun A (s: serial A) : A -> A -> Prop := proj1_sig s.
Coercion serial_to_fun : serial >-> Funclass.
Well. It is just not able to "understand" that you want it to coerce to relation nat.
When you write Check (bar foo). coq should unify type which the bar is expecting (namely relation nat) and the type which foo has (namely serial nat). So, coq tryes to unify serial nat and relation nat and since these types are not convertable, coq "understands" that it needs try to use coercion. So, it tryes to find coercion from serial nat to relation nat. And since you have provided such a coercion, it succeeds.
Edit.
When you write Check (foo 1 2). coq will try to unify type of the foo (namely serial nat) and type of function like (nat -> nat -> A) . So, again, it just does able not see that you want it to coerce foo to relation nat.

Interfaces: parametrise over value or use higher-kindedness?

I'm trying to get my head around the difference between these three interfaces, and when to use each
interface Foo (xs : List Nat) (n : Nat) bar where
...
interface Foo' (xs : List Nat) (bar : Nat -> Type) where
...
interface Foo'' (bar : List Nat -> Nat -> Type) where
...
I assume it's similar to Functor vs Show, but I'm a bit vague on that too. Any thoughts?
Context
I currently use Foo', and I'm using it in a type alias
Baz : Foo' xs bar => Type
Baz {bar} = forall m . Vect m Double -> bar m
but at usage site I need to specify xs twice: Baz {xs=[1]} {bar=MyFoo [1]} for some Foo' xs (MyFoo' xs) where, which I don't really understand because there's only one possible value that could work for xs in the application of Baz. I'm exploring the others to see if they work (no success yet), but I'm not very clear on what the API implications of each are.

How does one print the entire contents of a proof object or Gallina terms in Coq?

How does one print and expand everything in a Coq term (e.g. implicits, notations, definition, everything)? I want to print absolutely everything (including the contents of the identifiers).
For example with a term, I tried a modest example with Set Printing All. but it didn't work as I expect. My script is:
Module print_everything.
Definition id {A:Type} (x:A) := x.
Print id.
Definition id2 := #id.
Print id2.
Set Printing All.
Print id2.
Print All.
End.
but when I sent it to coq I got:
id2 = #id
: forall (A : Type) (_ : A), A
but I expect the body of the function, something like this:
id2 = fun (A : Type) (x : A) => x
: forall (A : Type) (_ : A), A
or
id = fun (A : Type) (x : A) => x
: forall (A : Type) (_ : A), A
How does one remove all "abstractions", including notation, implicit and even identifiers
so that I can see the entire lambda term (ideally when passing a Gallina term to Print_everything)?
If possible I'd like to control the scopes of which definitions are unpacked for me too. e.g. global variables qualid . qualid.
How does one print and expand everything in a Coq term (e.g. implicits, notations, definition, everything)?
It would also be nice to be able to expand and simplify as much as possible.
Related:
How to temporarily disable notations in Coq
https://coq.discourse.group/t/how-to-unset-printing-everything-e-g-implicits-notations-etc/1364/4
it seems Show Proof. works in the middle of a proof: https://www.seas.upenn.edu/~cis500/cis500-f14/sf/ProofObjects.html and https://softwarefoundations.cis.upenn.edu/lf-current/ProofObjects.html

Defining subtype relation in Coq

Is there a way to define subtype relationship in Coq?
I read about subset typing, in which a predicate is used to determine what goes into the subtype, but this is not what I am aiming for. I just want to define a theory in which there is a type (U) and another type (I), which is subtype of (U).
There is no true subtyping in Coq (except for universe subtyping, which is probably not what you want). The closest alternative is to use coercions, which are functions that the Coq type checker inserts automatically whenever it is expecting an element of one type but finds an element of another type instead. For instance, consider the following coercion from booleans to natural numbers:
Definition nat_of_bool (b : bool) : nat :=
if b then 1 else 0.
Coercion nat_of_bool : bool >-> nat.
After running this snippet, Coq uses nat_of_bool to convert bool to nat, as shown here:
Check true + 3.
(* true + 3 : nat *)
Thus, bool starts behaving almost as if it were a subtype of nat.
Though nat_of_bool does not appear here, it is just being hidden by Coq's printer. This term is actually the same thing as nat_of_bool true + 3, as we can see by asking Coq to print all coercions:
Set Printing Coercions.
Check true + 3.
(* nat_of_bool true + 3 : nat *)
The :> symbol you had asked about earlier, when used in a record declaration, is doing the same thing. For instance, the code
Record foo := Foo {
sort :> Type
}.
is equivalent to
Record foo := Foo {
sort : Type
}.
Coercion sort : foo >-> Sortclass.
where Sortclass is a special coercion target for Type, Prop and Set.
The Coq user manual describes coercions in more detail.

Why FMapAVL usage in argument is non strictly positive while list is?

Consider the following code:
Require Import FMapAVL.
Require Import Coq.Structures.OrderedTypeEx.
Module NatMap := FMapAVL.Make(Nat_as_OT).
Inductive ttree (K : Type) (V : Type) :=
| tleaf : ttree K V
| tnode : ttree K V -> K -> V -> ttree K V -> nat -> ttree K V.
Inductive test :=
| test1 : test
| test2 : ttree nat test -> test
| test3 : list test -> test
| test4 : NatMap.t test -> test.
In Coq 8.6, I get Error: Non strictly positive occurrence of "test" in "NatMap.t test -> test". I get no error without test4.
Why does applying a NatMap.t (FMapAVL with nat keys) constructor to my test inductive type creates a non strictly positive occurence while applying list constructor or even ttree constructor (which is just like internal structure of FMapAVL) okay?
What are the common workarounds if I want something like test4 from my example, preferably ones not requiring me to make my own map implementation like that ttree?
The problem is that Coq can't handle some higher-order inductive types as nested inductives - I'm not convinced I fully understand the limitations, but I investigated a bit.
One important fact that helps explain the behavior is that Coq has special support for passing an inductive type to a type constructor. CPDT's Inductive Types chapter explains this in the section on Nested Inductive Types: Coq creates a version of list or ttree specialized to test and pretends you're defining tree and these specialized inductives with mutual induction. This generally works fine (such as for your list and even ttree definitions). It even works for modules, as long as they use "transparent ascription" (and FMapAVL.Make does so). However, it seems to break down when the type is an index instead of a parameter (that is, when the Type is to the right of the colon instead of the left):
Module Type Transformer.
Axiom T:Type -> Type.
End Transformer.
Module IdOpaque : Transformer.
Definition T (t:Type) := t.
End IdOpaque.
Inductive transformer : Type -> Type :=
| MkT : forall t, t -> transformer t .
(* make the argument a parameter *)
Inductive transformer' (t:Type) : Type :=
| MkT' : t -> transformer' t.
Module IdInd <: Transformer.
Definition T : Type -> Type := transformer.
End IdInd.
Module IdTransparent <: Transformer.
Definition T (t:Type) : Type := t.
End IdTransparent.
(* works with a simple definition, even inside a module, as long as its
transparent *)
Inductive test1 :=
| mkTest1 (_:IdTransparent.T test1).
(* not strictly positive (Coq can't see definition) *)
Fail Inductive test2 :=
| mkTest2 (_:IdOpaque.T test2).
(* this is pretty much what happens with FMapAVL.Make *)
Fail Inductive test3 :=
| mkTest3 (_:IdInd.T test3).
(* even this fails *)
Fail Inductive test4 :=
| mkTest4 (_:transformer test4).
(* this finally works *)
Inductive test5 :=
| mkTest5 (_:transformer' test5).