(** * Skelet #10 *)
(** Following https://www.sligocki.com/2023/03/14/skelet-10.html *)
Set Default Goal Selector "!".
Definition tm : TM := fun '(q, s) =>
match q, s with
| A, 0 => Some (1, R, B)  | A, 1 => Some (0, R, A)
| B, 0 => Some (0, L, C)  | B, 1 => Some (1, R, A)
| C, 0 => Some (1, R, E)  | C, 1 => Some (1, L, D)
| D, 0 => Some (1, L, C)  | D, 1 => Some (0, L, D)
| E, 0 => None            | E, 1 => Some (0, R, B)
end.
Notation "c --> c'" := (c -[ tm ]-> c')   (at level 40).
Notation "c -->* c'" := (c -[ tm ]->* c') (at level 40).
Notation "c -->+ c'" := (c -[ tm ]->+ c') (at level 40).
Inductive dorf : Set :=
| zend : dorf
| zO : dorf -> dorf
| zIO : dorf -> dorf.
(* Note: We don't actually need to define [val] for the proof to go through. It's just useful to sanity-check the definition. *)
Fixpoint val' (n : dorf) (prev cur : nat) : nat :=
match n with
| zend => 0
| zO n' => val' n' cur (cur + prev)
| zIO n' => cur + val' n' (cur + prev) (cur + prev + cur)
end.
Definition val (n : dorf) : nat := val' n 1 1.
Example val_11 : val (zO (zO (zIO (zIO zend)))) = 11.

Lemma incr_val : forall n,
val (incr n) = S (val n).