Coq: break the (co) inductive hypothesis without losing information

Consider the following development:

Require Import Relation RelationClasses.

Set Implicit Arguments.

CoInductive stream (A : Type) : Type :=
| scons : A -> stream A -> stream A.

CoInductive stream_le (A : Type) {eqA R : relation A}
                      `{PO : PartialOrder A eqA R} :
                      stream A -> stream A -> Prop :=
| le_step : forall h1 h2 t1 t2, R h1 h2 ->
            (eqA h1 h2 -> stream_le t1 t2) ->
            stream_le (scons h1 t1) (scons h2 t2).

If I have a hypothesis stream_le (scons h1 t1) (scons h2 t2), it would be wise for tactics to destructturn it into a couple of hypotheses R h1 h2and eqA h1 h2 -> stream_le t1 t2. But this is not what happens because it destructloses information when it does something non-trivial. Instead, the new members are introduced in context h0, h3, t0, t3, do not remind you that they are, respectively h1, h2, t1, t2.

I would like to know if there is a quick and easy way to make this smart destruct. Here is what I have right now:

Theorem stream_le_destruct : forall (A : Type) eqA R
  `{PO : PartialOrder A eqA R} (h1 h2 : A) (t1 t2 : stream A),
  stream_le (scons h1 t1) (scons h2 t2) ->
  R h1 h2 /\ (eqA h1 h2 -> stream_le t1 t2).
Proof.
  intros.
  destruct H eqn:Heq.
  remember (scons h1 t1) as s1 eqn:Heqs1;
  remember (scons h2 t2) as s2 eqn:Heqs2;
  destruct H;
  inversion Heqs1; subst; clear Heqs1;
  inversion Heqs2; subst; clear Heqs2.
  split; assumption.
Qed.
+4
source share
2

, inversion , , , , - .

inversion destruct, . , Coq "" , , , .

? , I : Idx -> Prop : I x -> Q x, I x x Q. , I term Q (f term) , I x -> x = term -> Q (f x). , I x, x, .

case: Coq 8.7;

From Coq Require Import ssreflect.
Theorem stream_le_destruct A eqA R `{PO : PartialOrder A eqA R} (h1 h2 : A) (t1 t2 : stream A) :
  stream_le (scons h1 t1) (scons h2 t2) ->
  R h1 h2 /\ (eqA h1 h2 -> stream_le t1 t2).
Proof.
move E1: (scons h1 t1) => sc1; move E2: (scons h2 t2) => sc2 H.
by case: sc1 sc2 / H E1 E2 => h1' h2' t1' t2' hr ih [? ?] [? ?]; subst.
Qed.

, ; , . case: , , , , .

+4

destruct , . inversion.

Theorem stream_le_destruct : forall h1 h2 t1 t2,
  stream_le (scons h1 t1) (scons h2 t2) ->
  h1 <= h2 /\ (h1 = h2 -> stream_le t1 t2).
Proof.
  intros.
  inversion H; subst; clear H.
  split; assumption.
Qed.

, inversion , , . ( , ) - inversion , , , inversion.

+3

Source: https://habr.com/ru/post/1681635/


All Articles