So, I'm pretty sure this should be possible without choice. Maybe I am wrong.
Here is a minimal reproducible example of what I'm trying to do:
Record MRE :=
{ set : Prop
; elem : set
; op : set -> set -> set
; subset : Prop
; subset_incl : subset -> set
; exist_axiom : forall (f : subset -> set), exists (x : set), f = fun y => op (subset_incl y) x
; uniq_axiom : forall (f : subset -> set), forall (x : set),
f = (fun y => op (subset_incl y) x) -> x = ex_proj1 (exist_axiom f)
}.
I used "intensional" equality here, and I'm not sure if that makes it too strict. Perhaps "extensional" equality needs to be used in the hypothesis of the uniqueness axiom in order to do what I want.
In essence, we have a subset of this structure such that any function from the subset into the structure can be represented using the intrinsic operation op
. A very strong property, indeed. Since this representation is unique, there should be a way to produce a "derivative" of any given function from the structure to itself. Here's what I mean:
Definition witness_fcn : forall (M : MRE),
forall (f : set M -> set M),
exists (fn : set M -> set M),
forall (x : subset M),
(fun y => f (op M (subset_incl M x) y)) = (fun y => op M (subset_incl M x) (fn y)).
Proof.
intros M f.
pose (fn0 := fun y => exist_axiom M (fun x => f (op M (subset_incl M x) y))).
exists (fun y => ex_proj1 (fn0 y)).
intros x.
unfold fn0.
I'm not at all sure how to continue the proof from there, or if I even started it correctly.
This question asks something similar, but without the assumption of uniqueness. The question is answered here, but doesn't really go into detail on how a uniqueness property like this would be used in a proof.
Hypothetically, at least in regular math, it should follow directly from the definition of fn0
, but I'm not sure how to express that.
In the two links you mention, the problem is the segregation enforced by Coq between propositions (those types of type Prop
) and other types (those with type Set
or Type
), with the idea being that proofs should not be needed for programs to run. However, in your case both set M
and subset M
are propositions, so this separation is not a problem: as you saw when defining fn0
, Coq is perfectly happy to use the first component of your existential type to build the function you are looking for. This is a good point of constructive mathematics: modulo the separation between Prop
and Type
, choice is simply true!
Rather, the problem comes from the second part of the proof, i.e. the proof of equality of functions. It is a subtle issue of Coq that equality of functions is not extensional, that is the following axiom cannot, in general, be proven
Axiom fun_ext : forall {A B : Type} {f g : A -> B}, (forall x, f x = g x) -> f = g.
My intuition for this is that the equality of functions in Coq is more fine-grained than being the equality of output, as it distinguishes between functions that compute the same output in different ways. This is somewhat sensible as you might wish to distinguish between functions with different complexity for instance. However, this is more often than not considered a defect, and various extensions/variations on Coq’s type theory try and provide systems where this axiom is true.
Using this axiom, your theorem becomes quite straightforwardly provable (not that the uniqueness does not play a role, only the existence):
Definition witness_fcn : forall (M : MRE),
forall (f : set M -> set M),
exists (fn : set M -> set M),
forall (x : subset M),
(fun y => f (op M (subset_incl M x) y)) = (fun y => op M (subset_incl M x) (fn y)).
Proof.
intros M f.
pose (fn0 := fun y => exist_axiom M (fun x => f (op M (subset_incl M x) y))).
exists (fun y => ex_proj1 (fn0 y)).
intros x.
unfold fn0.
eapply fun_ext.
intros z.
destruct (fn0 z).
cbn.
etransitivity.
1: change (f (op M (subset_incl M x) z)) with ((fun x' => f (op M (subset_incl M x') z)) x) ; rewrite e.
all: reflexivity.
Defined.
I am not completely sure that your theorem is not provable without function extensionality, but that seems quite probable to me. If you wish to avoid it, you should try and get rid of the equality of functions. A usual way to do so is to use pointwise equality directly, that is to replace f = g
with forall x, f x = g x
.