how to create a polymorphe couple such as "( a : type A, b : type B ) " in lambda-calculus - coq

I am working on a project in Lambda-calculus and i am trying to code polymorphe couple with coqide
but a have a problem coding the constructor that respect the type pprod
Definition pprod : Set -> Set -> Set := fun A B => forall T : Set , (A -> B -> T) -> T.
I have a problem with pcpl
Definition pcpl : Set -> Set -> pprod :=
fun A B T : Set => fun (a : A) (b : B) => fun k : A -> B -> T => k a b.
this is the error i get :
The term "pprod" has type "Set -> Set -> Set"
which should be Set, Prop or Type.

The problem is that you are quantifying over Set, so the resulting product type cannot be of type Set, but of a larger type Type. So your definition should look like
Definition pprod : Set -> Set -> Type := fun A B => forall T : Set , (A -> B -> T) -> T.
the constructor for products should look like
Definition pcpl (A : Set) (B : Set) : A -> B -> pprod A B :=
fun (a : A) (b : B) => fun T : Set => fun k : A -> B -> T => k a b.
An alternative way to approach this is to use the polymorphic types in Coq, namely the types in Prop:
Definition pprod : Prop -> Prop -> Prop :=
fun A B => forall T : Prop , (A -> B -> T) -> T.
Definition pcpl (A : Prop) (B : Prop) : A -> B -> pprod A B :=
fun (a : A) (b : B) => fun T : Prop => fun k : A -> B -> T => k a b.
Note the universes in Coq are a bit confusing. See What is different between Set and Type in Coq? for details.
I'm going to take this opportunity to advertise the new Proof Assistants stack exchange.

Related

RelationClasses versus CRelationClasses

The Coq standard library has two subsets of classes modules, one anchored in Coq.Classes.RelationClasses and the other in Coq.Classes.CRelationClasses. The latter seems to have been added more recently (2012).
I must be missing something obvious as they both look very similar to me.
What is the reason they exist?
The key difference is in the type of relations they support:
(* RelationClasses, actually defined in Relation_Definitions *)
Definition relation (A : Type) := A -> A -> Prop.
(* CRelationClasses *)
Definition crelation (A : Type) := A -> A -> Type.
In addition to crelation producing a Type instead of a Prop, another key difference is that crelation is universe polymorphic, but relation is not.
Require Import Relation_Definitions.
Require Import Coq.Classes.CRelationClasses.
Set Printing Universes.
Print relation.
(*
relation =
fun A : Type#{Coq.Relations.Relation_Definitions.1} => A -> A -> Prop
: Type#{Coq.Relations.Relation_Definitions.1} ->
Type#{max(Set+1,Coq.Relations.Relation_Definitions.1)}
*)
Print crelation.
(*
crelation#{u u0} =
fun A : Type#{u} => A -> A -> Type#{u0}
: Type#{u} -> Type#{max(u,u0+1)}
(* u u0 |= *)
*)
Check (fun (R: crelation (Type -> Type)) => R crelation).
Fail Check (fun (R: relation (Type -> Type)) => R relation).
(*
The command has indeed failed with message:
In environment
R : relation (Type#{test.7} -> Type#{test.8})
The term "relation" has type
"Type#{Coq.Relations.Relation_Definitions.1} ->
Type#{max(Set+1,Coq.Relations.Relation_Definitions.1)}"
while it is expected to have type "Type#{test.7} -> Type#{test.8}"
(universe inconsistency: Cannot enforce Coq.Relations.Relation_Definitions.1
<= test.8 because test.8 < Coq.Relations.Relation_Definitions.1).
*)

Is the %hint annotation imported/Dec and auto annotation?

I have a datatype that depends on a predicate P : a -> Type, meaning that some of its data constructors refer have an implicit P x as argument. I would like idris to be able to automatically infer this implicit. For this, I annotated the implicit with the keyword auto and I wrote a function isP : (x : a) -> Dec (P x) with a %hint annotation before the type declaration. Namely, something like:
module P
P : a -> Type
%hint
isP : (x : a) -> Dec (P x)
and in a separate file
module Main
import P
data Foo : Type where
Bar : (x : a) -> .{auto prf : P x} -> Foo
That said, I can't declare values of said Foo type because Idris claims the it can't infer prf.
Is this because prf has type P x instead of Dec (P x) or is it because the %hint flag does not get imported?
In either case, how can I get Idris to use a Dec value to try to find an implicit?
The %hint flag is imported, as you guess, it's because Dec (P x) is different than P x.
There's a trick though, you can use this datatype:
data IsYes : prop -> Type where
SoTrue : IsYes (Yes prop)
(basically, you define a type that holds a Yes for a given property)
and then you can use default instead of auto to check if the property holds:
data Foo : Type where
Bar : (x : a) -> .{default SoTrue prf : IsYes (isP x)} -> Foo
Note: with this trick, you don't even need %hint anymore, you just check the outcome of isP at compile time.

Recursive use of typeclass methods in Coq

Is there a way to use recursion with Coq's typeclasses? Like for e.g., in defining show for lists, if you want to call the show function for lists recursively, then you will have to use a fixpoint like so:
Require Import Strings.String.
Require Import Strings.Ascii.
Local Open Scope string_scope.
Class Show (A : Type) : Type :=
{
show : A -> string
}.
Section showNormal.
Instance showList {A : Type} `{Show A} : Show (list A) :=
{
show :=
fix lshow l :=
match l with
| nil => "[]"
| x :: xs => show x ++ " : " ++ lshow xs
end
}.
End showNormal.
Which is all well and good, but what if I want to define some helper function that I'll use for defining Show instances? Like I want to create a more DAZZLING show function called magicShow that prints stars around something...
Definition magicShow {A : Type} `{Show A} (a : A) : string :=
"** " ++ show a ++ " **".
Instance showMagicList {A : Type} `{Show A} : Show (list A) :=
{
show :=
fix lshow l :=
match l with
| nil => "[]"
| x :: xs => show x ++ " : " ++ magicShow xs
end
}.
However, in this case Coq can't find a show instance for the list xs to pass to magicShow:
Error:
Unable to satisfy the following constraints:
In environment:
A : Type
H : Show A
lshow : list A -> string
l : list A
x : A
xs : list A
?H : "Show (list A)"
Is there any way to do this in general? I.e., can you define a method for a typeclass using functions that rely upon the typeclass instance that you're defining?
No, there's no way to do this. This works in Haskell because arbitrary recursive bindings are allowed, and the language doesn't care about the order of bindings. Coq is more restrictive on both fronts. This makes sense if you think about what the desugaring looks like: the recursive call to show would refer to the currently-being-defined instance by name, but that binding isn't in scope yet. And you can't make the instance itself a fixpoint because you're recursing on the structure of a type, not on a value of an algebraic data type.
Your inline fixpoint works for show, but the problem gets thornier if your method implementations refer to each other, such as
newtype MyInteger = MyInteger Integer
instance Num MyInteger where
MyInteger m + MyInteger n = MyInteger $ m + n
negate (MyInteger m) = MyInteger $ negate m
m - n = m + negate n
-- other methods
Here, the calls to (+) and negate in the definition of (-) needs to refer to the definitions of (+) and negate above, but this also doesn't work in Coq. The only solution is to define all your methods separately, manually referencing each other, and then define the instance simply by setting each method to the one you defined above. For example,
Inductive MyInteger := Mk_MyInteger : Integer -> MyInteger.
Definition add__MyInteger (m n : MyInteger) : MyInteger :=
let 'Mk_MyInteger m' := m in
let 'Mk_MyInteger n' := n in
Mk_MyInteger (add m' n').
Definition negate__MyInteger (m : MyInteger) : MyInteger :=
let 'Mk_MyInteger m' := m in
Mk_MyInteger (negate m').
Definition sub__MyInteger (m n : MyInteger) : MyInteger :=
add__MyInteger m (negate__MyInteger n).
Instance Num__MyInteger : Num MyInteger := {|
add := add__MyInteger;
negate := negate__MyInteger;
sub := sub__MyInteger;
(* other methods *)
|}.
If you must do this, it can be simulated by explicitly using the constructor of the underlying Record (since "Typeclasses are Records", to quote from Software Foundations [1]), which can be instantiated using the function(s) being defined as a fixpoint. I'll post three examples and explain where this can be useful.
The example you posted could be solved like this (all code tested for Coq 8.10.1):
Require Import Strings.String.
Local Open Scope list_scope.
Local Open Scope string_scope.
Class Show (A : Type) : Type :=
{
show : A -> string
}.
Definition magicShow {A : Type} `{Show A} (a : A) : string :=
"** " ++ show a ++ " **".
Print Show.
(* Record Show (A : Type) : Type := Build_Show { show : A -> string }
*)
Check Build_Show.
(* Build_Show : forall A : Type, (A -> string) -> Show A *)
Check #magicShow.
(* #magicShow : forall A : Type, Show A -> A -> string *)
Instance showMagicList {A : Type} `{Show A} : Show (list A) :=
{
show :=
fix lshow l :=
match l with
| nil => "[]"
| x :: xs => show x ++ " : " ++ #magicShow _ (#Build_Show _ lshow) xs
end
}.
If you are trying to define several typeclass methods like this, it's tricky to instantiate the record constructor, but it can be done by treating the functions as if they were defined by mutual recursion (although there doesn't necessarily have to be any actual mutual recursion). Here's a contrived example where Show now has two methods. Notice that the typeclass instance is added to the context with an anonymous let-in binding. Evidently, this is enough to satisfy Coq's typeclass resolution mechanism.
Require Import Strings.String.
Local Open Scope list_scope.
Local Open Scope string_scope.
Class Show (A : Type) : Type :=
{
show1 : A -> string
; show2 : A -> string
}.
Definition magicShow1 {A : Type} `{Show A} (a : A) : string :=
"** " ++ show1 a ++ " **".
Definition magicShow2 {A : Type} `{Show A} (a : A) : string :=
"** " ++ show2 a ++ " **".
Fixpoint show1__list {A : Type} `{Show A} (l : list A) : string :=
let _ := (#Build_Show _ show1__list show2__list) in
match l with
| nil => "[]"
| x :: xs => show1 x ++ " : " ++ magicShow1 xs
end
with show2__list {A : Type} `{Show A} (l : list A) : string :=
let _ := (#Build_Show _ show1__list show2__list) in
match l with
| nil => "[]"
| x :: xs => show1 x ++ " : " ++ magicShow2 xs
end.
Instance showMagicList {A : Type} `{Show A} : Show (list A) :=
{
show1 := show1__list
; show2 := show2__list
}.
So why would you want to do this? A good example is when you are defining decidable equality on (rose) trees. In the middle of the definition, we have to recursively appeal to decidable equality of list (tree A). We would like to use the standard library helper function Coq.Classes.EquivDec.list_eqdec [2], which shows how to pass decidable equality on a type A to list A. Since list_eqdec requires a typeclass instance (the very one we are in the middle of defining), we have to use the same trick above:
Require Import Coq.Classes.EquivDec.
Require Import Coq.Program.Utils.
Set Implicit Arguments.
Generalizable Variables A.
Inductive tree (A : Type) : Type :=
| leaf : A -> tree A
| node : list (tree A) -> tree A.
Program Instance tree_eqdec `(eqa : EqDec A eq) : EqDec (tree A) eq :=
{ equiv_dec := fix tequiv t1 t2 :=
let _ := list_eqdec tequiv in
match t1, t2 with
| leaf a1, leaf a2 =>
if a1 == a2 then in_left else in_right
| node ts1, node ts2 =>
if ts1 == ts2 then in_left else in_right
| _, _ => in_right
end
}.
Solve Obligations with unfold not, equiv, complement in * ;
program_simpl ; intuition (discriminate || eauto).
Next Obligation.
destruct t1;
destruct t2;
( program_simpl || unfold complement, not, equiv in *; eauto ).
Qed.
Solve Obligations with split; (intros; try unfold complement, equiv ; program_simpl).
(*
No more obligations remaining
tree_eqdec is defined
*)
Commentary: There is no constructor for creating a record of type EqDec (since it only has one class method), so to convince Coq that list (tree A) has decidable equality, the invocation is simply list_eqdec tequiv. For the uninitiated, Program here is simply allowing for holes in the definition of the instance to be filled in later as Obligations, which is more convenient than writing the appropriate proofs inline.

How to capture parameters under universal quantification (using Modules? Sections?)

I am wondering how best to handle this sort of situation in Coq:
Suppose I need to define and prove a number of things about an arbitrary structure (for the purposes of this discussion, let's say a set with a binary relation). Of course, I can always supply the set and relation as arguments for each such definition/proof:
Inductive star (X : Set) (R : X -> X -> Prop) := ...
Lemma star_trans (X : Set) (R : X -> X -> Prop) : ...
Naturally, this gets tiresome after a while. What I would like to do is have X and R as parameters locally within some demarcated area of code like so:
Parameter X : Set.
Parameter R : X -> X -> Prop.
Inductive star := ...
Lemma star_trans : ...
in such a way that the definitions and theorems, when used outside this area of code, capture X and R under universal quantification in order to give them the proper type. For instance, Check star should yield star : forall X : Set, (X -> X -> Prop) -> X -> X -> Prop.
I figured that this might be what modules are for, but I can't figure out how to use them for this situation.
This is exactly what the "Section mechanism" does: see https://coq.inria.fr/distrib/current/refman/Reference-Manual004.html#Section .
Section rel_star.
Variables (X : Set) (R : X -> X -> Prop).
Inductive star := ...
Lemma star_trans: ...
End rel_star.

Coq type error when matching with type family

I’m trying to re-implement an example from CPDT from memory. I wrote:
Inductive myType : Set := MyNat | MyBool.
Definition typeDenote (t : myType) : Set :=
match t with
| MyNat => nat
| MyBool => bool
end.
Inductive unaryOp : myType -> myType -> Set :=
| Twice : unaryOp MyNat MyNat.
Definition twice (n:nat) : nat := n + n.
Definition tunaryDenote (a b : myType) (t : unaryOp a b)
: typeDenote a -> typeDenote b :=
match t with
| Twice => twice
end.
The resulting error is:
Toplevel input, characters 125-130
> | Twice => twice
> ^^^^^
Error: In environment
a : myType
b : myType
t : unaryOp a b
The term "twice" has type "nat -> nat" while it is expected to have type
"forall H : typeDenote ?141, typeDenote ?142"
I don’t understand this error message. I would think that once the match on Twice : unaryOp MyNat MyNat succeeds, Coq infers that a and b are MyNats, and thus typeDenote a -> typeDenote b ≡ nat -> nat, making twice a perfectly fine candidate for the return value. Where’d I go wrong?
Just like #AntonTrunov said, it is typechecked without any issue on my Coq 8.5pl1. However if you need to add some extra annotations for your version to accept the function, you want to have a look at this section of the manual to figure out what to do.
My guess is that you want to have a match ... in ... return ... with to say that the return type should be refined by the information obtained by matching t at the type unaryOp a b (indeed: a and b will take concrete values in the Twice branch).
This is the definition you get using that technique:
Definition tunaryDenote (a b : myType) (t : unaryOp a b)
: typeDenote a -> typeDenote b :=
match t in unaryOp a b return typeDenote a -> typeDenote b with
| Twice => twice
end.
I think that the answer is that Coq's type inference is limited, and does not do the reasoning you want it to do.
Coq's type inference does not do arbitrary calculation but simple unification. It looks at twice, understand that it is nat->nat and concludes that it is not (syntactically) of the form typeDenote a -> TypeDenote b.
If it was doing calculation, it was likely to be non-terminating, since its type system is very sophisticated so you can encode non-trivial computation there.
I tried a newer version of Coq, and like others have said, it typechecks without issue on Coq 8.5. :)