Meaning of ⊗ applied to morphisms - category-theory

I think I understand what ⊗ means when applied to objects (such as M ⊗ M), but what does it mean when applied to morphisms (such as η⊗1). Is it just composition?

Assuming the question is about monoidal categories (for which https://math.stackexchange.com/ is the more appropriate site), ⊗ : C x C -> C is a functor, and therefore has an action on objects and on morphisms. Given objects X, X', Y, Y' in C and morphisms x : X -> X' and y : Y -> Y', x ⊗ y : X ⊗ Y -> X' ⊗ Y' is a morphism in C.

Related

Agda: Failed to solve the following constraints: P x <= _X_53 (blocked on _X_53)

I'm writing Agda code as I read the HoTT book. I'm stuck on Lemma 2.3.9:
data _≡_ {X : Set} : X -> X -> Set where
refl : {x : X} -> x ≡ x
infix 4 _≡_
-- Lemma 2.1.2
_·_ : {A : Set} {x y z : A} -> x ≡ y -> y ≡ z -> x ≡ z
refl · refl = refl
-- Lemma 2.3.1
transp : {A : Set} {P : A -> Set} {x y : A} -> x ≡ y -> P x -> P y
transp refl f = f
lemma2'3'9 : {A : Set}{P : A -> Set}{x y z : A}{p : x ≡ y}{q : y ≡ z}{u : P x} ->
(transp q (transp p u)) ≡ (transp (p · q) u)
lemma2'3'9 {p = refl} {q = refl} = ?
Type-checking with Adga Emacs Mode gives me the following error:
?0 : transp refl (transp refl u) ≡ transp (refl · refl) u
_X_53 : Set [ at /home/user/prog/agda/sample.agda:12,38-39 ]
———— Errors ————————————————————————————————————————————————
Failed to solve the following constraints:
P x =< _X_53 (blocked on _X_53)
Questions
What is '_X_53', and why is it greater than or equal to (P x)?
How can I get rid of this error?
Note
I wrote a working example of Lemma 2.3.9 in Coq, so I'm assuming it's possible in Agda.
Inductive eq {X:Type} (x: X) : X -> Type :=
| refl : eq x x.
Notation "x = y" := (eq x y)
(at level 70, no associativity)
: type_scope.
Definition eqInd{A} (C: forall x y: A, x = y -> Type) (c: forall x: A, C x x (refl x)) (x y: A): forall p: x = y, C x y p :=
fun xy: x = y => match xy with
| refl _ => c x
end.
Definition dot'{A}{x y: A}: x = y -> forall z: A, y = z -> x = z :=
let D := fun x y: A => fun p: x = y => forall z: A, forall q: y = z, x = z in
let d: forall x, D x x (refl x) := let E: forall x z: A, forall q: x = z, Type := fun x z: A => fun q: x = z => x = z in
let e := fun x => refl x
in fun x z => fun q => eqInd E e x z q
in fun p: x = y => eqInd D d x y p.
(* Lemma 2.1.2 *)
Definition dot{A}{x y z: A}: x = y -> y = z -> x = z :=
fun p: x = y => dot' p z.
Definition id {A} := fun a: A => a.
(* Lemma 2.3.1 *)
Definition transp{A} {P: A -> Type} {x y: A}: x = y -> P x -> P y :=
fun p =>
let D := fun x y: A => fun p: x = y => P x -> P y in
let d: forall x, D x x (refl x) := fun x => id
in eqInd D d x y p.
Lemma L_2_3_9{A}{P: A -> Type}{x y z: A}{p: x = y}{q: y = z}{u: P x}:
transp q (transp p u) = transp (dot p q) u.
Proof.
unfold transp, dot, dot'.
rewrite <- q.
rewrite <- p.
reflexivity.
Qed.
_X_53 is a meta variable, i.e., an unknown part of a term. In order to figure out this unknown part of the term, Agda tries to resolve the meta variable. She does so by looking at the context the meta variable appears in, deriving constraints from this context, and determining possible candidate solutions for the meta variable that meet the constraints.
Among other things, Agda uses meta variables to implement implicit arguments. Each implicit argument is replaced with a meta variable, which Agda then tries to resolve within a context that includes the remaining arguments. This is how values for implicit arguments can be derived from the remaining arguments, for example.
Sometimes Agda is unable to figure out an implicit argument, even though one would think that she should be able to. I.e., Agda is unable to resolve the implicit argument's meta variable. This is when she needs a little assistance, i.e., we have to explicitly specify one or more of the implicit arguments. Which is what #gallais suggests in the comment.
=< compares two types. A =< B means that something of type A can be put where something of type B is required. So, if you have a function that takes a B, you can give it an A and it'll type check. I think that this is mostly used for Agda's sized types. In your case, I think, this can be read as type equality instead.
But back to the error message. Agda fails to find a solution for _X_53. The constraint that needs to be met is P x =< _X_53. If, in your case, =< is type equality, then why doesn't Agda simply set _X_53 to P x?
According to my very limited understanding, the reason is higher-order unification, which is a bit of a - to use a very technical term - capricious and finicky beast. _X_53 isn't the complete truth here. Meta variables can be functions and thus have arguments. According to the Agda debug log, the actual unification problem at hand is to unify _X_53 A P x x and P x. If I remember things correctly, then the two xs in the former are a problem. Take this with a grain of salt, though. I'm not a type theorist.
Long story short, sometimes Agda fails to figure out an implicit argument because unification fails and it's a bit hard to understand why exactly.
Finally, something related: The following article talks a bit about best practices for using implicit arguments: Inference in Agda
Update
I guess the two xs are a problem, because they keep Agda from finding a unique solution to the unification problem. Note that both, λ a b c d. P c and λ a b c d. P d would work for _X_53 in that both would make _X_53 A P x x reduce to P x.

Is there a shorter proof to this Coq theorem?

I'm learning to use Coq and I try to prove the theorems of a paper I'm reading. The paper is Having a Part Twice Over of Karen Bennett, published in 2013. The paper propopes a mereological theory composed of two primitives F and Ps and defines the parthood relation P using the two primitives.
I coded it as follows:
Class Entity: Type.
(* Slot Mereology defines the parthood relation
* with the two primitives F and Ps.
* The idea is that wholes have slots
* filled by their parts.
* F x s means that x fills slot s.
* Ps s y means that s is a parthood slot of y.
* P is the parthood relation.
*)
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
(* Slot Inheritance *)
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
(* Parthood Transitivity *)
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
intros x y z.
unfold P.
intro h.
destruct h as (EsPxy, EsPyz).
destruct EsPxy as (s1, Pxy).
destruct Pxy as (Fxs1, Pss1y).
destruct EsPyz as (s2, Pyz).
destruct Pyz as (Fys2, Pss2z).
exists s1.
split.
apply Fxs1.
apply A5 with (z1 := s2) (x := y).
split.
split.
assumption.
assumption.
assumption.
Qed.
I succeeded to prove theorem T7. I have two questions:
is my Coq code ok? (I'm not sure If the way I declared the type, the primitives and the predicate is the right way to do it.)
is there a shorter proof? (About the length of the proof, I only want to know about the number of tactics.)
Another approach, using ssreflect and its neat notation for destructuring, one can rephrase your explicit proof in a more compact way (I'm using Arthur's version).
From mathcomp Require Import all_ssreflect.
Parameter Entity: Type.
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
move=> x y z [[s1 [Fxs1 Ps1y]] [s2 [Fys2 Ps2z]]].
by exists s1; split; [|exact: (A5 y z s2 s1)].
Qed.
Yes, your Coq code is OK. But there are shorter proofs. This theorem is simple enough that it can be solved with Coq's automation tactics. E.g.,
Parameter Entity: Type.
(* Slot Mereology defines the parthood relation
* with the two primitives F and Ps.
* The idea is that wholes have slots
* filled by their parts.
* F x s means that x fills slot s.
* Ps s y means that s is a parthood slot of y.
* P is the parthood relation.
*)
Parameter F : Entity -> Entity -> Prop.
Parameter Ps : Entity -> Entity -> Prop.
Definition P (x y : Entity) :=
exists s, F x s /\ Ps s y.
(* Slot Inheritance *)
Axiom A5 : forall x y z1 z2 : Entity,
(Ps z1 y /\ F x z1) /\ Ps z2 x -> Ps z2 y.
(* Parthood Transitivity *)
Theorem T7 : forall x y z : Entity,
(P x y /\ P y z) -> P x z.
Proof.
unfold P; firstorder; eauto 10 using A5.
Qed.
(Notice that I replaced "Class Entity" with "Parameter Entity": The first form is actually just defining a type whose elements are records with no fields, whereas the second one is postulating that the type Entity exists without placing any further constraints on it.)

How can I generalise Coq proofs of an iff?

A common kind of proof I have to make is something like
Lemma my_lemma : forall y, (forall x x', Q x x' y) -> (forall x x', P x y <-> P x' y).
Proof.
intros y Q_y.
split.
+ <some proof using Q>
+ <the same proof using Q, but x and x' are swapped>
where Q is itself some kind of iff-shaped predicate.
My problem is that the proofs of P x y -> P x' y and P x' y -> P x y are often basically identical, with the only difference between that the roles of x and x' are swapped between them. Can I ask Coq to transform the goal into
forall x x', P x y -> P x' y
which then generalises to the iff case, so that I don't need to repeat myself in the proof?
I had a look through the standard library, the tactic index, and some SO questions, but nothing told me how to do this.
Here is a custom tactic for it:
Ltac sufficient_if :=
match goal with
| [ |- forall (x : ?t) (x' : ?t'), ?T <-> ?U ] => (* If the goal looks like an equivalence (T <-> U) (hoping that T and U are sufficiently similar)... *)
assert (HHH : forall (x : t) (x' : t'), T -> U); (* Change the goal to (T -> U) *)
[ | split; apply HHH ] (* And prove the two directions of the old goal *)
end.
Parameter Q : nat -> nat -> nat -> Prop.
Parameter P : nat -> nat -> Prop.
Lemma my_lemma : forall y, (forall x x', Q x x' y) -> (forall x x', P x y <-> P x' y).
Proof.
intros y Q_y.
sufficient_if.
In mathematics, one often can make "assumptions" "without loss of generality" (WLOG) to simplify proofs of this kind. In your example, you could say "assume without loss of generality that P x y holds. To prove P x y <-> P x' y it is sufficient to prove P x' y."
If you are using ssreflect, you have the wlog tactic.
You essentially cut in another goal which can easily solve your goal. You can also do it with standard tactics like assert or enough (which is like assert but the proof obligations are in the other order).
An example to show what I mean: below I just want to show the implication in one direction, because it can easily solve the implication in the other direction (with firstorder).
Context (T:Type) (P:T->T->Prop).
Goal forall x y, P x y <-> P y x.
enough (forall x y, P x y -> P y x) by firstorder.
Now I just have to show the goal in one direction, because it implies the real goal's both directions.
For more about WLOG see for instance 1

Notation for reflexive transitive closure in Coq

Consider the reflexive transitive closure of a relation:
Inductive star {A : Type} (r : A -> A -> Prop) : A -> A -> Prop :=
| star_refl x : star r x x
| star_step x y z : r x y -> star r y z -> star r x z.
How can I give notation in Coq so that I can write x ->* y, perhaps adding a subscript to represent the relation ->__r. This is certainly possible in Isabelle. Is there a clean way of doing it in Coq?
You can indeed use the notation system of Coq for this:
Notation "x '[' R ']*' y" := (star R x y) (at level 20).
Goal
forall A (x y z : A) R,
x [R]* y ->
y [R]* z ->
x [R]* z.
There are other notations that you can try, this an example explicitly mentioning the R.
You can only use this generic notation in combination with a special one for reduction.
Section Terms.
Context (term : Type).
Context (red : term -> term -> Prop).
Notation "x → y" := (red x y) (at level 0).
Notation "x →* y" := (x [red]* y) (at level 19).
Goal forall x y, x → y -> x →* y.
Abort.
End Terms.
Also note that you can do something fancy and use the notation already in the definition.
Reserved Notation "x '[' R ']*' y" (at level 20).
Inductive star {A : Type} (r : A -> A -> Prop) : A -> A -> Prop :=
| star_refl x : x [r]* x
| star_step x y z : r x y -> y [r]* z -> x [r]* z
where "x '[' R ']*' y" := (star R x y).
You can do a lot of things with notations. The following also works.
Notation "x '→<' R '>*' y" := (star R x y) (at level 20).
Goal
forall A (x y z : A) R,
x →<R>* y ->
y →<R>* z ->
x →<R>* z.
Abort.

How to formalize the termination of a term reduction relation in Coq?

I have a term rewriting system (A, →) where A is a set and → a infix binary relation on A. Given x and y of A, x → y means that x reduces to y.
To implement some properties I simply use the definitions from Coq.Relations.Relation_Definitions and Coq.Relations.Relation_Operators.
Now I want to formalize the following property :
→ is terminating, that is : there is no infinite descending chain a0 → a1 → ...
How can I achieve that in Coq ?
Showing that a rewriting relation terminates is the same thing as showing that it is well-founded. This can be encoded with an inductive predicate in Coq:
Inductive Acc {A} (R : A -> A -> Prop) (x: A) : Prop :=
Acc_intro : (forall y:A, R x y -> Acc R y) -> Acc R x.
Definition well_founded {A} (R : A -> A -> Prop) :=
forall a:A, Acc R a.
(This definition is essentially the same one of the Acc and well_founded predicates in the standard library, but I've changed the order of the relation to match the conventions used in rewriting systems.)
Given a type A and a relation R on A, Acc R x means that every sequence of R reductions starting from x : A is terminating; thus, well_founded R means that every sequence starting at any point is terminating. (Acc stands for "accessible".)
It might not be very clear why this definition works; first, how can we even show that Acc R x holds for any x at all? Notice that if x is an element does not reduce (that is, such that R x y never holds for any y), then the premise of Acc_intro trivially holds, and we are able to conclude Acc R x. For instance, this would allow us to show Acc gt 0. If R is indeed well-founded, then we can work backwards from such base cases and conclude that other elements of A are accessible. A formal proof of well-foundedness is more complicated than that, because it has to work generically for every x, but this at least shows how we could show that each element is accessible separately.
OK, so maybe we can show that Acc R x holds. How do we use it, then?
With the induction and recursion principles that Coq generates for Acc; for instance:
Acc_ind : forall A (R : A -> A -> Prop) (P : A -> Prop),
(forall x : A, (forall y : A, R x y -> P y) -> P x) ->
forall x : A, Acc R x -> P x
When R is well-founded, this is simply the principle of well-founded induction. We can paraphrase it as follows. Suppose that we can show that P x holds for any x : A while making use of an induction hypothesis that says that P y holds whenever R x y. (Depending on the meaning of R, this could mean that x steps to y, or that y is strictly smaller than x, etc.) Then, P x holds for any x such that Acc R x. Well-founded recursion works similarly, and intuitively expresses that a recursive definition is valid if every recursive call is performed on "smaller" elements.
Adam Chlipala's CPDT has a chapter on general recursion that has a more comprehensive coverage of this material.