Set Implicit Arguments.
Require Import List Lia std axioms.
Import ListNotations.

Multiplication Motivation

Section Motivation.

  Variable (a b m n p: ).

  Definition succ '(a, b) := (n + a, 1 + b).
  Definition ith i := (i * n + a, i + b).

  Section Streams.

    Implicit Type (X Y: ( * )).

    Definition charac {A: Type} (X: A) (a: A) (Y: A) :=
      X 0 = a n, X (S n) = Y n.

    Notation "X ≈ Y ⟶ Z" := (charac X Y Z) (at level 60).

    Definition Succ X := X >> succ.

    Let X := ith.

    Lemma X_satisfies:
      X (a, b) Succ X.
    Proof.
      split; unfold X, ith; cbn; intros; f_equal; lia.
    Qed.


    Lemma X_unique Y:
      (Y (a, b) Succ Y) i, Y i = X i.
    Proof.
      intros H; induction i.
      - destruct H as [H _]. rewrite H. unfold X, ith. now simplify.
      - destruct H as [_ H]. unfold Succ, funcomp in *.
        rewrite H, IHi. unfold X, ith; cbn; f_equal; lia.
    Qed.


  End Streams.

  Section FiniteSequences.
    Implicit Type (X Y: list ( * )).

    Notation succ' X := (map succ X).

    Lemma forward: p = m * n X, (a,b) :: succ' X = X [(p + a, m + b)].
    Proof.
      intros . exists (tab ith m).
      rewrite tab_map. change (tab _ _ _) with (tab ith (S m)).
      rewrite tab_S. unfold ith, succ. cbn. rewrite !tab_map_nats.
      f_equal. eapply map_ext. intros i. f_equal; lia.
    Qed.


    Lemma backward' X x:
      (a, b) :: succ' X = X [x] x = ith (length X).
    Proof.
      unfold ith. induction X as [|[l r] X IH] in a, b, x |-*; eauto.
      - cbn; simplify. intuition congruence.
      - simplify. intros [= H]. eapply IH in H; subst.
        cbn; simplify; f_equal; lia.
    Qed.



    Lemma backward X:
      (a,b) :: succ' X = X [(p + a, m + b)] m * n = p.
    Proof.
      intros H % backward'. injection H.
      intros; assert (m = |X|) as by lia. lia.
    Qed.

  End FiniteSequences.


End Motivation.