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

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.

Related

Fix vs. Fix_sub

I'm attempting to use Fix to express a well-founded function.
It has Fix_eq to unwrap it for 1 level, however, the confusing
part is that Fix_eq is expressed in terms of Fix_sub instead of Fix.
The difference appears to be that
Check Fix.
(* ... *)
(forall x : A, (forall y : A, R y x -> P y) -> P x) ->
Check Fix_sub.
(* ... *)
(forall x : A, (forall y : {y : A | R y x}, P (proj1_sig y)) -> P x) ->
Fix uses 2 arguments and Fix_sub packages them both together into a sig.
So, they are essentially equivalent. However, I don't see any included
convenience functions to switch between Fix and Fix_sub. Is there
a reason that Fix_eq doesn't work with Fix ? How is it supposed
to be used?
I'm aware of Program and Function, but here I am trying to use Fix directly.
Which version and libraries are you using?
in 8.16 I get
Fix_eq:
forall [A : Type] [R : A -> A -> Prop] (Rwf : well_founded R)
(P : A -> Type) (F : forall x : A, (forall y : A, R y x -> P y) -> P x),
(forall (x : A) (f g : forall y : A, R y x -> P y),
(forall (y : A) (p : R y x), f y p = g y p) -> F x f = F x g) ->
forall x : A, Fix Rwf P F x = F x (fun (y : A) (_ : R y x) => Fix Rwf P F y)
and Fib_subis unknown.
You may have imported some module which masks the definitions from Coq.Init.Wf ?

How to use a definition in Coq?

Sometimes when I'm proving something, I have a hypothesis P x y, and I know that I have a definition like R x := exists y, P x y. I would like to add the hypothesis R x, but I don't know how to do it. I tried to use pose proof (R x), but I got something of type Prop. Is there a way to do it?
If you have a hypothesis Hxy: P x y, you can write
assert (Rx: R x) by (exists y; assumption).
On the other direction, if you have a hypothesis Hx: R x, the tactic destruct Hx as [y Pxy] adds the witness yand the corresponding hypothesis to your context.
You can add a new argument to your lemma, and inside the proof, you can then extract a witness y' for your y. In ssreflect, you could write:
From mathcomp Require Import all_ssreflect.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Variable T : Type.
Variable P : T -> T -> Prop.
Definition R x := exists y, P x y.
Lemma foo x y (p : P x y) (r : R x) : false.
Proof.
move: r => [y' pxy'].
EDIT: You can also derive a proof of R x directly in the proof of foo, as follows:
Lemma foo x y (p : P x y) : false.
Proof.
have r : R x by exists y.
move: r => [y' pxy'].
or, more succinctly:
Lemma foo x y (p : P x y) : false.
Proof.
have [y' pxy'] : R x by exists y.
``

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.

Implementing/specifying permutation groups in coq

I am trying to implement/specify the permutation groups (symmetric groups) in coq. This went well for a bit, until I tried to prove that the identity is actually the identity. My proof gets stuck on proving that the proposition "x is invertible" is exactly the same as the proposition "id * x is invertible".
Are these two propositions actually the same? Am I trying to prove something that is not true? Is there a better way of specifying the permutation group (as a type)?
(* The permutation group on X contains all functions between X and X that are bijective/invertible *)
Inductive G {X : Type} : Type :=
| function (f: X -> X) (H: exists g: X -> X, forall x : X, f (g x) = x /\ g (f x) = x).
(* Composing two functions preserves invertibility *)
Lemma invertible_composition {X : Type} (f g: X -> X) :
(exists f' : X -> X, forall x : X, f (f' x) = x /\ f' (f x) = x) ->
(exists g' : X -> X, forall x : X, g (g' x) = x /\ g' (g x) = x) ->
exists h : X -> X, forall x : X, (fun x => f (g x)) (h x) = x /\ h ((fun x => f (g x)) x) = x.
Admitted.
(* The group operation is composition *)
Definition op {X : Type} (a b : G) : G :=
match a, b with
| function f H, function g H' => function (fun x => f (g x)) (#invertible_composition X f g H H')
end.
Definition id' {X : Type} (x : X) : X := x.
(* The identity function is invertible *)
Lemma id_invertible {X : Type} : exists g : X -> X, forall x : X, id' (g x) = x /\ g (id' x) = x.
Admitted.
Definition id {X : Type} : (#G X) := function id' id_invertible.
(* The part on which I get stuck: proving that composition with the identity does not change elements. *)
Lemma identity {X: Type} : forall x : G, op id x = x /\ #op X x id = x.
Proof.
intros.
split.
- destruct x.
simpl.
apply f_equal.
Abort.
I believe that your statement cannot be proved without assuming extra axioms:
proof_irrelevance:
forall (P : Prop) (p q : P), p = q.
You need this axiom to show that two elements of G are equal when the underlying functions are:
Require Import Coq.Logic.ProofIrrelevance.
Inductive G X : Type :=
| function (f: X -> X) (H: exists g: X -> X, forall x : X, f (g x) = x /\ g (f x) = x).
Arguments function {X} _ _.
Definition fun_of_G {X} (f : G X) : X -> X :=
match f with function f _ => f end.
Lemma fun_of_G_inj {X} (f g : G X) : fun_of_G f = fun_of_G g -> f = g.
Proof.
destruct f as [f fP], g as [g gP].
simpl.
intros e.
destruct e.
f_equal.
apply proof_irrelevance.
Qed.
(As a side note, it is usually better to declare the X parameter of G explicitly, rather than implicitly. It is rarely the case that Coq can figure out what X should be on its own.)
With fun_of_G_inj, it should be possible to show identity simply by applying it to each equality, because fun a => (fun x => x) (g a) is equal to g for any g.
If you want to use this representation for groups, you'll probably also need the axiom of functional extensionality eventually:
functional_extensionality:
forall X Y (f g : X -> Y), (forall x, f x = g x) -> f = g.
This axiom is available in the Coq.Logic.FunctionalExtensionality module.
If you want to define the inverse element as a function, you probably also need some form of the axiom of choice: it is necessary for extracting the inverse element g from the existence proof.
If you don't want to assume extra axioms, you have to place restrictions on your permutation group. For instance, you can restrict your attention to elements with finite support -- that is, permutation that fix all elements of X, except for a finite set. There are multiple libraries that allow you to work with permutations this way, including my own extensional structures.

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.