Notation for reflexive transitive closure in Coq - 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.

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.

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

Partial differentiation using Coqelicot on Coq

I want to partially differentiate functions which expects n arguments for arbitrary natural number n. I hope to differentiate arbitrary an argument only once and not the others.
Require Import Reals.
Open Scope R_scope.
Definition myFunc (x y z:R) :R:=
x^2 + y^3 + z^4.
I expect function 3*(y^2) when I differentiate myFunc with y.
I know partial_derive in Coquelicot.
Definition partial_derive (m k : nat) (f : R → R → R) : R → R → R :=
fun x y ⇒ Derive_n (fun t ⇒ Derive_n (fun z ⇒ f t z) k y) m x.
partial_derive can partially differentiate f:R → R → R, but not possible for arbitrary number of arguments.
I thought about using dependent type listR.
Inductive listR :nat -> Type:=
|RO : Euc 0
|Rn : forall {n}, R -> listR n -> listR (S n).
Notation "[ ]" := RO.
Notation "[ r1 , .. , r2 ]" := (Rn r1 .. ( Rn r2 RO ) .. ).
Infix ":::" := Rn (at level 60, right associativity).
Fixpoint partial_derive_nth {n} (k:nat) (f : listR n -> R) (e:listR n): listR n -> R:=
k specifies argument number to differentiate.
We can not define partial_derive_nth like partial_derive because we can not specify the name of arguments of fun in recursion.
Please tell me how to partially differentiate functions which has arbitrary number of arguments.
For your function myFunc, you can write the partial derivative like so:
Definition pdiv2_myFunc (x y z : R) :=
Derive (fun y => myFunc x y z) y.
You can then prove that it has the value you expect for any choice of x, y, and z. Most of the proof can be done automatically, thanks to the tactics provided in Coquelicot.
Lemma pdiv2_myFunc_value (x y z : R) :
pdiv2_myFunc x y z = 3 * y ^ 2.
Proof.
unfold pdiv2_myFunc, myFunc.
apply is_derive_unique.
auto_derive; auto; ring.
Qed.
I am a bit surprised that the automatic tactic auto_derive does not handle a goal of the form Derive _ _ = _, so I have to apply theorem is_derive_unique myself.

Efficient Way of Defining Multiple Functions of the Same Type

I would like to avoid copying and pasting the parameters and return type of functions of the same type that I am trying to define. Since, in my opinion, that would be bad programming practice.
For example, I am defining the following functions:
Definition metric_non_negative {X : Type} (d : X -> X -> R) :=
forall x y : X, (d x y) >= 0.
Definition metric_identical_arguments {X : Type} (d : X -> X -> R) :=
forall x y : X, (d x y) = 0 <-> x = y.
I would like to be able to define both functions without repeatedly typing the redundancy:
{X : Type} (d : X -> X -> R)
I would also like to potentially define a third function, in which case the solution should generalize to the case where more than two functions of the same type are being defined. Is this possible, and how so?
As Anton Trunov mentioned in his comment, it sounds exactly like you want to use a section:
Section Metric.
Context {X: Type}.
Variable (d: X -> X -> nat).
Definition metric_non_negative :=
forall x y : X, (d x y) >= 0.
Definition metric_identical_arguments :=
forall x y : X, (d x y) = 0 <-> x = y.
End Metric.
Note that I've used Context to make X an implicit argument; you can also use Set Implicit Arguments. and make it a Variable to let Coq set its implicitness automatically.

Termination implies existence of normal form

I would like to prove that termination implies existence of normal form. These are my definitions:
Section Forms.
Require Import Classical_Prop.
Require Import Classical_Pred_Type.
Context {A : Type}
Variable R : A -> A -> Prop.
Definition Inverse (Rel : A -> A -> Prop) := fun x y => Rel y x.
Inductive ReflexiveTransitiveClosure : Relation A A :=
| rtc_into (x y : A) : R x y -> ReflexiveTransitiveClosure x y
| rtc_trans (x y z : A) : R x y -> ReflexiveTransitiveClosure y z ->
ReflexiveTransitiveClosure x z
| rtc_refl (x y : A) : x = y -> ReflexiveTransitiveClosure x y.
Definition redc (x : A) := exists y, R x y.
Definition nf (x : A) := ~(redc x).
Definition nfo (x y : A) := ReflexiveTransitiveClosure R x y /\ nf y.
Definition terminating := forall x, Acc (Inverse R) x.
Definition normalizing := forall x, (exists y, nfo x y).
End Forms.
I'd like to prove:
Lemma terminating_impl_normalizing (T : terminating):
normalizing.
I have been banging my head against the wall for a couple of hours now, and I've made almost no progress. I can show:
Lemma terminating_not_inf_forall (T : terminating) :
forall f : nat -> A, ~ (forall n, R (f n) (f (S n))).
which I believe should help (this is also true without classic).
Here is a proof using the excluded middle. I reformulated the problem to replace custom definitions by standard ones (note by the way that in your definition of the closure, the rtc_into is redundant with the other ones). I also reformulated terminating using well_founded.
Require Import Classical_Prop.
Require Import Relations.
Section Forms.
Context {A : Type} (R:relation A).
Definition inverse := fun x y => R y x.
Definition redc (x : A) := exists y, R x y.
Definition nf (x : A) := ~(redc x).
Definition nfo (x y : A) := clos_refl_trans _ R x y /\ nf y.
Definition terminating := well_founded inverse. (* forall x, Acc inverse x. *)
Definition normalizing := forall x, (exists y, nfo x y).
Lemma terminating_impl_normalizing (T : terminating):
normalizing.
Proof.
unfold normalizing.
apply (well_founded_ind T). intros.
destruct (classic (redc x)).
- destruct H0 as [y H0]. pose proof (H _ H0).
destruct H1 as [y' H1]. exists y'. unfold nfo.
destruct H1.
split.
+ apply rt_trans with (y:=y). apply rt_step. assumption. assumption.
+ assumption.
- exists x. unfold nfo. split. apply rt_refl. assumption.
Qed.
End Forms.
The proof is not very complicated but here are the main ideas:
use well founded induction
thanks to the excluded middle principle, separate the case where x is not in normal form and the case where it is
if x is not in normal form, use the induction hypothesis and use the transitivity of the closure to conclude
if x is already in normal form, we are done