Pairs and projections in Coq - coq

I took the following code from https://coq.inria.fr/library/Coq.Init.Datatypes.html:
Inductive prod (A B:Type) : Type :=
pair : A -> B -> A * B
where "x * y" := (prod x y) : type_scope.
Add Printing Let prod.
Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope.
Section projections.
Context {A : Type} {B : Type}.
Definition fst (p:A * B) := match p with (x, y) => x end.
Definition snd (p:A * B) := match p with (x, y) => y end.
End projections.
When I load it into CoqIDE, at Definition fst... it comes up with the message The constructor pair (in type prod) expects 4 arguments.. How can I resolve this problem?

Add
Set Implicit Arguments.
to the top of the file.

Related

Non strictly positive occurrence problem in Coq inductive definition

The main problem is I cannot define such an Inductive proposition:
Inductive forces : nat -> Prop :=
| KM_cond (n : nat) : ~ forces 0 ->
forces n.
In fact, I am trying to define the Kripke Semantics for Intuitionistic Logic
Inductive forces (M : Kripke_model) (x : world) : prop -> Prop :=
| KM_cond (A B : prop) : set_In x (worlds M) ->
(forall y, (rel M) x y -> (~ forces M y A \/ forces M y B)) ->
forces M x (A then B).
but I get the following error
Non strictly positive occurrence of "forces"
If I just remove the negation, the problem goes away
Inductive forces (M : Kripke_model) (x : world) : prop -> Prop :=
| KM_cond (A B : prop) : set_In x (worlds M) ->
(forall y, (rel M) x y -> (forces M y A \/ forces M y B)) ->
forces M x (A then B).
but the problem exists with -> also
Inductive forces (M : Kripke_model) (x : world) : prop -> Prop :=
| KM_cond (A B : prop) : set_In x (worlds M) ->
(forall y, (rel M) x y -> (forces M y A -> forces M y B)) ->
forces M x (A then B).
I cannot understand what would possibly go wrong if I define this Inductive thing, and I cannot think of any other way to achieve this definition.
UPDATE:
These are the needed definitions:
From Coq Require Import Lists.List.
From Coq Require Import Lists.ListSet.
From Coq Require Import Relations.
Import ListNotations.
Definition var := nat.
Inductive prop : Type :=
| bot
| atom (p : var)
| conj (A B : prop)
| disj (A B : prop)
| cond (A B : prop).
Notation "A 'and' B" := (conj A B) (at level 50, left associativity).
Notation "A 'or' B" := (disj A B) (at level 50, left associativity).
Notation "A 'then' B" := (cond A B) (at level 60, no associativity).
Definition world := nat.
Definition preorder {X : Type} (R : relation X) : Prop :=
(forall x : X, R x x) /\ (forall x y z : X, R x y -> R y z -> R x z).
Inductive Kripke_model : Type :=
| Kripke (W : set world) (R : relation world) (v : var -> world -> bool)
(HW : W <> empty_set world)
(HR : preorder R)
(Hv : forall x y p, In x W -> In y W ->
R x y -> (v p x) = true -> (v p y) = true).
Definition worlds (M : Kripke_model) :=
match M with
| Kripke W _ _ _ _ _ => W
end.
Definition rel (M : Kripke_model) :=
match M with
| Kripke _ R _ _ _ _ => R
end.
Definition val (M : Kripke_model) :=
match M with
| Kripke _ _ v _ _ _ => v
end.
You cannot define this relation as an inductive predicate, but you can define it by recursion on the formula:
Fixpoint forces (M : Kripke_model) (x : world) (p : prop) : Prop :=
match p with
| bot => False
| atom p => val M p x = true
| conj p q => forces M x p /\ forces M x q
| disj p q => forces M x p \/ forces M x q
| cond p q => forall y, rel M x y -> forces M y p -> forces M y q
end.
This trick does not work if the definition is not well-founded with respect to the formula structure, but it might be enough for your use case.

Enforce immediate typeclass instance resolution

Is there a way to enforce that when a typeclass is used, a particular instance is immediately found?
Right, now I'm getting an existential variable when there is no instance available, but I want to get an error.
A simple example will explain much better what I'm trying to achieve. I'm trying to get a function evaluation with implicit casting for certain types. In this case I want to have only one possible implicit cast X' -> X.
Class Evaluation (A B C : Type) : Type :=
{
cast_eval : (A -> B) -> C -> B
}.
Instance DirectEvaluation (A B : Type) : Evaluation A B A :=
{
cast_eval := fun f x => f x
}.
Parameter (X X' X'' Y : Type) (f : X -> Y) (x : X) (x' : X') (x'' : X'') (x_cast : X' -> X).
Instance XDashEvaluation : Evaluation X Y X' :=
{
cast_eval := fun ff xx => f (x_cast xx)
}.
Compute (cast_eval f x). (* f x *)
Compute (cast_eval f x'). (* f (x_cast x') *)
Compute (cast_eval f x''). (* (let (cast_eval) := ?Evaluation in cast_eval) f x'' *)
Is there a way to get an error when calling (cast_eval f x'')?
One way to get an error would be make a Definition first:
Definition e := cast_eval f x''.
Compute e.

What <> is in Coq

It's difficult to search for but wondering what <> means as in here:
Axiom point : Type.
Axiom line : Type.
Axiom lies_in : point -> line -> Prop.
Axiom ax : forall (p1 p2 : point), p1 <> p2 ->
exists! l : line, lies_in p1 l /\ lies_in p2 l.
x <> y is a notation for ~(x = y) (which itself is a notation for (x = y) -> False). It's possible to search for notations with the Locate vernacular command, which is used like Locate "<>". and gives output like
Notation
"x <> y :> T" := not (eq x y) : type_scope
(default interpretation)
"x <> y" := not (eq x y) : type_scope
(default interpretation)
The x <> y form is a notation for not (x = y) -- that is, it asserts that it is not the case that x and y are equal. Negation is defined by setting not P := P -> False. In other words, by showing P, we obtain a contradiction.

Error: Illegal application (Non-functional construction)

I'm trying to work some proofs of the various deMorgans laws using the type constructors/eliminators from the HoTT book. I had hopped to pick through https://mdnahas.github.io/doc/Reading_HoTT_in_Coq.pdf for relevant stuff and dump it all into a .v text file. I need Elimination/Introduction rules for product, co-product and a way to set up negation. So far I have,
Definition idmap {A:Type} (x:A) : A := x.
Inductive prod {A B:Type} : Type := pair : A -> B -> #prod A B.
Notation "x * y" := (prod x y) : type_scope.
Section projections.
Context {A : Type} {B : Type}.
Definition fst (p: A * B ) :=
match p with
| (x , y) => x
end.
Definition snd (p:A * B ) :=
match p with
| (x , y) => y
end.
End projections.
The Error on "Definition fst (p: A * B ) :=" is
Error: Illegal application (Non-functional construction):
The expression "prod" of type "Type"
cannot be applied to the term
"A" : "Type"
I tried searching through the error list on the Coq site but didn't find anything.
There are two issues with your code:
prod's two Type arguments are declared implicit
As a consequence, the notation "x * y" corresponds to prod {_} {_} x y which will always lead to ill-typed terms: prod {_} {_} is a Type and as such it does not make sense to apply something to it.
The fix is to turn these two implicit arguments into explicit ones:
Inductive prod (A B:Type) : Type := pair : A -> B -> #prod A B.
The notation (x , y) has not been declared
Once you've fixed the definition of prod, the definition still don't typecheck because Coq does not know what you mean by the pattern (x, y). You can declare it as a new notation before your Section projections like so:
Notation "x , y" := (pair _ _ x y) (at level 10).

Error: The reference fst was not found in the current environment

I am writing a small program so that I can work some proofs of deMorgans laws using the type introduction/elimination rules from the HoTT book (et. al.). My model/example code is all here, https://mdnahas.github.io/doc/Reading_HoTT_in_Coq.pdf. So far I have,
Definition idmap {A:Type} (x:A) : A := x.
Inductive prod (A B:Type) : Type := pair : A -> B -> #prod A B.
Notation "x * y" := (prod x y) : type_scope.
Notation "x , y" := (pair _ _ x y) (at level 10).
Section projections.
Context {A : Type} {B : Type}.
Definition fst (p: A * B ) :=
match p with
| (x , y) => x
end.
Definition snd (p:A * B ) :=
match p with
| (x , y) => y
end.
End projections.
Inductive sum (A B : Type ) : Type :=
| inl : A -> sum A B
| inr : B -> sum A B.
Arguments inl {A B} _ , [A] B _.
Arguments inr {A B} _ , A [B].
Notation "x + y" := (sum x y) : type_scope.
Inductive Empty_set:Set :=.
Inductive unit:Set := tt:unit.
Definition Empty := Empty_set.
Definition Unit := unit.
Definition not (A:Type) : Type := A -> Empty.
Notation "~ x" := (not x) : type_scope.
Variables X:Type.
Variables Y:Type.
Goal (X * Y) -> (not X + not Y).
intro h. fst h.
Now I don't really know what the problem is. I've examples of people using definitions, but they always involve "Compute" commands, and I want to apply the rule fst to h to get x:X, so they are not helpful.
I tried "apply fst." which got me
Error: Cannot infer the implicit parameter B of fst whose type is
"Type" in environment:
h : A * B
In a proof context, Coq expects to get tactics to execute, not expressions to evaluate. Since fst is not defined as a tactic, it will give Error: The reference fst was not found in the current environment.
One possible tactic to execute along the lines of what you seem to be trying to do is set:
set (x := fst h).
I want to apply the rule fst to h to get x:X
I believe you can do
apply fst in h.
If you just write apply fst, Coq will apply the fst rule to the goal, rather than to h. If you write fst h, as Daniel says in his answer, Coq will attempt to run the fst tactic, which does not exist. In addition to Daniel's set solution, which will change the goal if fst h appears in it (and this may or may not be what you want), the following also work:
pose (fst h) as x. (* adds x := fst h to the context *)
pose proof (fst h) as x. (* adds opaque x : X to the context, justified by the term fst h *)
destruct h as [x y]. (* adds x : X and y : Y to the context, and replaces h with pair x y everywhere *)