(* Token Factory definitions and proofs. We specify token factories and tokens inductively on trees, which makes the proofs fairly straightforward. *)
Inductive isTokenFactory' : ShareTree -> nat -> Prop :=
| isTokFac_0 : isTokenFactory' (Leaf true) O
| isTokFac_S_true : forall t n,
isTokenFactory' t (S n) ->
isTokenFactory' (Node (Leaf true) t) (S n)
| isTokFac_S_false : forall t n,
isTokenFactory' t n ->
isTokenFactory' (Node (Leaf false) t) (S n).
Inductive isToken' : ShareTree -> nat -> Prop :=
| isTok_0 : isToken' (Leaf false) O
| isTok_S_true : forall t n,
isToken' t n ->
isToken' (Node (Leaf true) t) (S n)
| isTok_S_false : forall t n,
isToken' t (S n) ->
isToken' (Node (Leaf false) t) (S n).
Definition isTokenFactory (x:t) (n:nat) := isTokenFactory' (proj1_sig x) n.
Definition isToken (x:t) (n:nat) := isToken' (proj1_sig x) n.

(* Specifications: *)
Lemma isTokenFactory_canon : forall n fac,
isTokenFactory' fac n -> canonicalTree fac.
Lemma isToken_canon : forall n tok,
isToken' tok n -> canonicalTree tok.