2
votes

I have an Inductive Set built with three constructors:

Inductive MF : Set :=
| D : MF
| cn : MF -> MF -> MF
| dn : Z -> MF -> MF.

I would like to somehow define a new inductive set B, such that B is a subset of MF containing just the elements obtained from D and dn. Furthermore, everything in B should be interpreted as type MF if needed.

I tried defining first B and then MF as follows:

Inductive B : Set :=
| D : B
| dn : Z -> B -> B.

Inductive MF : Set :=
| m : B -> MF
| cn : MF -> MF -> MF
| Dn : Z -> MF -> MF.
Axiom m_inj : forall (a b : B), m a = m b -> a = b.
Coercion m : B >-> MF.
Axiom dnDn : forall (a : B)(i : Z), (m (dn i a)) = (Dn i (m a)).

The problem here is that I have to constructors (dn and Dn) that should be interchangable with respect the elements in B. This gives me a lot of problems in further developments and I have to keep adding Axioms in order to get the intended behavior.

2

2 Answers

4
votes

Note that you will have to prove that isB mf enjoys proof irrelevance in your setting, otherwise Coq won't know that the projection mf is injective. Usually, you'd like equality in MF to imply equality in your subtype B.

I suggest the following variation:

Require Import Bool ZArith Eqdep_dec.

Inductive MF : Set :=
  | D : MF
  | cn : MF -> MF -> MF
  | dn : Z -> MF -> MF.

Inductive isB : MF -> Prop :=
  | DIsOK  : isB D
  | dnIsOK : forall z mf, isB mf -> isB (dn z mf).

Fixpoint isBb (mf : MF) : bool :=
  match mf with
  | D       => true
  | dn _ mf => isBb mf
  | _       => false
  end.

Lemma mfP mf : reflect (isB mf) (isBb mf).
Proof.
apply iff_reflect; split.
+ elim mf; auto; simpl; intros mf1 ihmf1 mf2 ihmf2.
  - now intros hisB; inversion hisB.
  - now inversion ihmf2; rewrite mf2.
+ now elim mf; simpl; try repeat (auto||constructor||congruence).
Qed.

Record B := mkB
  { mf  : MF
  ; prf : isBb mf = true
  }.

Coercion mf : B >-> MF.

(* From http://cstheory.stackexchange.com/questions/5158/prove-proof-irrelevance-in-coq *)
Theorem bool_pirrel : forall (b : bool) (p1 p2 : b = true), p1 = p2.
Proof.
intros; apply Eqdep_dec.eq_proofs_unicity; intros.
now destruct (Bool.bool_dec x y); tauto.
Qed.

Lemma valB b1 b2 : mf b1 = mf b2 -> b1 = b2.
Proof.
destruct b1, b2; simpl; intros ->.
now rewrite (bool_pirrel (isBb mf1) prf0 prf1).
Qed.

The math-comp library has great and systematic support for subtypes over boolean predicates, you may want to give it a go if you find yourself dealing with many subtypes.

1
votes

You can define B as a record packaging an MF element together with a proof that it is built using only D and dn. To this end, you need to start by defining a predicate isB : MF -> Prop describing the elements of MF which are Bs.

Require Import ZArith.

Inductive MF : Set :=
  | D : MF
  | cn : MF -> MF -> MF
  | dn : Z -> MF -> MF.

Inductive isB : MF -> Prop :=
  | DIsOK  : isB D
  | dnIsOK : forall z mf, isB mf -> isB (dn z mf).

Record B := mkB
  { mf  : MF
  ; prf : isB mf
  }.

Coercion mf : B >-> MF.