Coq Index Relation - coq

I'm defining an indexed inductive type in Coq:
Module Typ.
(* My index -- a t is a `t H` or a `t Z`. *)
Inductive hz : Set := H | Z .
(* I'd like to use this relation to constrain Cursor and Arrow. *)
(* E.g. one specialized Cursor has type `t H -> t Z -> t Z` *)
Inductive maxHZ : hz -> hz -> hz -> Type :=
| HZ : maxHZ H Z Z
| ZH : maxHZ Z H Z
| HH : maxHZ H H H
.
Inductive t : hz -> Type :=
| Num : t H
| Hole : t H
| Cursor : t H -> t Z
| Arrow : forall a b c, t a -> t b -> t c
| Sum : forall a b c, t a -> t b -> t c
.
End Typ.
How can I constrain my Arrow / Sum indices to be the same shape as the maxHZ relation (short of creating more constructors, like ArrowHZ : t H -> t Z -> t Z).

One approach:
(* Bring the coercion is_true into scope *)
From Coq Require Import ssreflect ssrfun ssrbool.
Module Typ.
(* My index -- a t is a `t H` or a `t Z`. *)
Inductive hz : Set := H | Z .
(* I'd like to use this relation to constrain Cursor and Arrow. *)
(* E.g. one specialized Cursor has type `t H -> t Z -> t Z` *)
Definition maxHZ (x y z : hz) : bool :=
match x, y, z with
| H, Z, Z
| Z, H, Z
| H, H, H => true
| _, _, _ => false
end.
Inductive t : hz -> Type :=
| Num : t H
| Hole : t H
| Cursor : t H -> t Z
| Arrow : forall a b c, maxHZ a b c -> t a -> t b -> t c
| Sum : forall a b c, maxHZ a b c -> t a -> t b -> t c
.
End Typ.
the other:
Inductive t : hz -> Type :=
| Num : t H
| Hole : t H
| Cursor : t H -> t Z
| Arrow : forall a b c, t a -> t b -> t c
| Sum : forall a b c, t a -> t b -> t c
.
Definition t_wf x (m : t x) : bool :=
match m with
| Arrow a b c _ _ => maxHZ a b c
| Sum a b c _ _ => maxHZ a b c
| _ => true
end.
Definition t' x := { m : t x | t_wf x m }.
(* This is automatically a subtype. *)

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 ?

Modeling Cardinality of Finite Sets in Coq

I have made a basic theory of finite sets in Coq.
Syntax of Finite Sets (fsets)
An fset_expr can be
the empty set, an add operation,
a filter (set comprehension) of another set,
a cup (union) of two sets,
or a cap (intersection) of two sets.
Inductive fset_expr { A : Set } : Set :=
| fset_expr_empty : fset_expr
| fset_expr_add : fset_expr -> A -> fset_expr
| fset_expr_filter : fset_expr -> (A -> bool) -> fset_expr
| fset_expr_cup : fset_expr -> fset_expr -> fset_expr
| fset_expr_cap : fset_expr -> fset_expr -> fset_expr.
Semantics of Set Membership
in_fset s a means that the s : fset_expr contains the member a.
Inductive in_fset { A : Set } : fset_expr (A:=A) -> A -> Prop :=
| in_fset_add : forall x a, in_fset (fset_expr_add x a) a
| in_fset_added : forall x a0 a1, in_fset x a0 -> in_fset (fset_expr_add x a1) a0
| in_fset_cup_l : forall x y a, in_fset x a -> in_fset (fset_expr_cup x y) a
| in_fset_cup_r : forall x y a, in_fset y a -> in_fset (fset_expr_cup x y) a
| in_fset_cap : forall x y a, in_fset x a -> in_fset y a -> in_fset (fset_expr_cap x y) a
| in_fset_filter : forall x f a, in_fset x a -> (f a = true) -> in_fset (fset_expr_filter x f) a.
Subsets and Set Equality
Definition is_empty_fset {A : Set} (s : fset_expr (A:=A)) :=
forall a, ~(in_fset s a).
Definition subset_fset {A : Set} (x y : fset_expr (A:=A)) :=
forall a, in_fset x a -> in_fset y a.
Definition eq_fset {A : Set} (x y : fset_expr (A:=A)) :=
subset_fset x y /\ subset_fset y x.
Cardinality
This is where complications occured. I defined cardinality_fset s n which is supposed to mean that the finite set s : fset_expr contains n : nat elements.
Inductive cardinality_fset { A : Set } : fset_expr (A:=A) -> nat -> Prop :=
| cardinality_fset_empty : cardinality_fset fset_expr_empty 0
| cardinality_fset_add : forall s n a,
~(in_fset s a) ->
cardinality_fset s n ->
cardinality_fset (fset_expr_add s a) (S n)
| cardinality_fset_trans :
forall x y n,
eq_fset x y ->
cardinality_fset x n ->
cardinality_fset y n.
Problem
I could not prove that cardinality is well defined, i.e. every congruence class of fset_expr under relation eq_fset has a unique cardinality. Is it possible?
forall s : fset_expr (A:=A), exists n, (cardinality_fset s n /\ forall s' n', eq_fset s s' -> cardinality_fset s' n' -> n' = n).
To prove that theorem, you need to be able to write a function cardinality : fset_expr -> nat that computes the cardinality of a finite set, and to do that, you will need to decide whether or not two elements (a1 a2 : A) are equal (so that you don't double-count).
If you include an assumption forall a1 a2 : A, {a1 = a2} + {a1 <> a2}, then your theorem should be provable.

Abstraction/typing error resulting from case_eq and rewriting in Coq

Consider the situation described by the code below, wherein I have a "piecewise" function h behaving differently (like f, or like g) depending on some (decidable) property condition of its input (h is defined using case_eq). Assume that I can prove that a property is guaranteed of the image of any x after application of either of the partial functions f or g; I should be able to prove that the entire function h guarantees property using a simple case_eq proof, no? Yet the following code rejects the rewrite step:
Section Error.
Variables X Y : Type.
Variables n m : Y.
Variable condition : X -> bool.
Variable property : Y -> Prop.
Definition type1 (x : X) : Prop := condition x = true.
Definition type2 (x : X) : Prop := condition x = false.
Variable f : {x:X | type1 x} -> Y.
Variable g : {x:X | type2 x} -> Y.
Definition h : X -> Y. intro x. case_eq (condition x); intro.
- exact (f (exist type1 x H)).
- exact (g (exist type2 x H)).
Defined.
Hypothesis Hf : forall x, property (f x).
Hypothesis Hg : forall x, property (g x).
Theorem hRange : forall x, property (h x).
Proof. intro. case_eq (condition x); intro.
- unfold h. rewrite H.
with the error
Abstracting over the term "condition x" leads to a term
fun b : bool =>
property
((if b as b0 return (b = b0 -> Y)
then fun H0 : b = true => f (exist type1 x H0)
else fun H0 : b = false => g (exist type2 x H0)) eq_refl)
which is ill-typed.
Reason is: Illegal application:
The term "exist" of type "forall (A : Type) (P : A -> Prop) (x : A), P x -> {x : A | P x}"
cannot be applied to the terms
"X" : "Type"
"type1" : "X -> Prop"
"x" : "X"
"H0" : "b = true"
The 4th term has type "b = true" which should be coercible to "type1 x".
Of course, I wish it would eliminate the if clause, rewriting the goal to property (f (exist type1 x H)) but Coq doesn't like this. Why not?
I feel Coq wouldn't behave like this if the hypothesis generated by case_eq in the definition of h wasn't implicated in the result (in this case, I could've rewritten h with a match clause, and those cause me no issue. In the present situation, just assume that the hypothesis is crucial to constructing some "non-computational" part of either f x or g x, e.g. if Y is itself a sig-type). I've read other threads like this and this, but to the short extent that I understand them, they don't help me understand my situation.
This problem occurs when you try to destruct or rewrite all the occurrences of a subterm. Here, you've rewritten condition x in the type of H0, which causes exist type1 x H0 to be ill-typed (can you see why?).
The solution is to restrict the destruct or rewrite to only some of the subterms. This might require you to generalize part of your goal. For example:
From Coq Require Import ssreflect.
Section Error.
Variables X Y : Type.
Variables n m : Y.
Variable condition : X -> bool.
Variable property : Y -> Prop.
Definition type1 (x : X) : Prop := condition x = true.
Definition type2 (x : X) : Prop := condition x = false.
Variable f : {x:X | type1 x} -> Y.
Variable g : {x:X | type2 x} -> Y.
Definition h : X -> Y. intro x. case_eq (condition x); intro.
- exact (f (exist type1 x H)).
- exact (g (exist type2 x H)).
Defined.
Hypothesis Hf : forall x, property (f x).
Hypothesis Hg : forall x, property (g x).
Theorem hRange : forall x, property (h x).
Proof.
intro; unfold h; generalize (eq_refl (condition x)).
case: {2 3}(condition x).
- intros H. apply Hf.
- intros H. apply Hg.
Qed.
End Error.
After generalizing eq_refl, the goal looks like this:
1 subgoal (ID 16)
X, Y : Type
n, m : Y
condition : X -> bool
property : Y -> Prop
f : {x : X | type1 x} -> Y
g : {x : X | type2 x} -> Y
Hf : forall x : {x : X | type1 x}, property (f x)
Hg : forall x : {x : X | type2 x}, property (g x)
x : X
============================
forall e : condition x = condition x,
property
((if condition x as b return (condition x = b -> Y)
then fun H : condition x = true => f (exist type1 x H)
else fun H : condition x = false => g (exist type2 x H)) e)
The tactic case: {2 3}..., which was imported from ssreflect, says that condition x should only be destructed on the RHS of e and on the condition of the if.

Converging sequence to least upper bound

Given a non-empty subset of the real numbers E : R -> Prop, the completeness axiom gives a least upper bound l of E.
Is there a constructive function
lub_approx_seq (E : R -> Prop) (l : R)
: is_lub E l -> forall n:nat, { x:R | E x /\ l-1/n < x }
In classical mathematics we would argue that for all n:nat, l-1/n is not an upper bound, so there exists an x such that E x /\ l-1/n < x.
But in constructive mathematics, ~forall (not an upper bound) is weaker than exists.
If it is not possible for a general subset E, are there conditions on E that make it possible ?
EDIT
I'm particularly interested in the case where E is a downward-infinite interval. Then the converging sequence is simply fun n:nat => l-1/n and what remains to be proved is :
Lemma lub_approx (E : R -> Prop) (l : R)
: is_lub E l
-> (forall x y : R, x < y -> E y -> E x) (* interval *)
-> forall x : R, x < l -> E x

Prove that one hypothesis is negation of another in Coq

For example I have these two hypotheses (one is negation of other)
H : forall e : R, e > 0 -> exists p : X, B e x p -> ~ F p
H0 : exists e : R, e > 0 -> forall p : X, B e x p -> F p
And goal
False
How to prove it?
You can't, because H0 is not the negation of H. The correct statement would be
Definition R := nat.
Parameter X: Type.
Parameter T: Type.
Parameter x: T.
Parameter B : R -> T -> X -> Prop.
Parameter F : X -> Prop.
Lemma foobar: forall (H: forall e : R, e > 0 -> exists p : X, B e x p -> ~ F p)
(H0: exists e: R, e > 0 /\ forall p: X, B e x p /\ F p), False.
Proof.
intros H H0.
destruct H0 as [e [he hforall]].
destruct (H e he) as [p hp].
destruct (hforall p) as [hB hF].
exact (hp hB hF).
Qed.