Set Warnings "-abstract-large-number".
Ltac invst H := inversion H; subst.
Ltac ctor := constructor.
Ltac ector := econstructor.
Ltac fext := apply functional_extensionality; intro.
Ltac gd x := generalize dependent x.
Ltac cg := try congruence.
Ltac clr_eqrefl:=
repeat match goal with
| H: ?A = ?A |- _ => clear H
end.
Ltac clr_dup:=
repeat match goal with
| H:?A, H':?A |- _ => clear H'
end.
Ltac clrs:=
clr_eqrefl; clr_dup.
Definition is_inj{T1 T2}(f:T1->T2):=
forall a b, f a = f b -> a = b.
Ltac ff_inj RR H := pose proof (ffx_eq_x_inj _ RR _ _ H); subst.
Fixpoint positive_len(x:positive):nat :=
match x with
| xH => O
| xI x0 => S (positive_len x0)
| xO x0 => S (positive_len x0)
end.
Fixpoint enc_v1(x:positive):positive :=
match x with
| xH => xH
| xI x0 => xI (xI (enc_v1 x0))
| xO x0 => xI (xO (enc_v1 x0))
end.
Definition enc_pair(x:positive*positive):positive :=
let (x1,x2):=x in
append (enc_v1 (Pos.of_succ_nat (positive_len x1))) (xO (append x1 x2)).
Fixpoint enc_list(x:list positive):positive :=
match x with
| nil => xH
| h::t => enc_pair (h,enc_list t)
end.
Notation "x &&& y" := (if x then y else false) (at level 80, right associativity).
Notation "x ||| y" := (if x then true else y) (at level 85, right associativity).
Definition set_ins{T}(enc:T->positive)(s:list T * PositiveMap.tree unit)(x:T):(list T * PositiveMap.tree unit)*bool :=
let enc := (enc x) in
match PositiveMap.find enc (snd s) with
| None => ((x::fst s, PositiveMap.add enc tt (snd s)),false)
| Some _ => (s,true)
end.
Definition set_in{T}(enc:T->positive)(s:list T * PositiveMap.tree unit)(x:T):Prop :=
PositiveMap.find (enc x) (snd s) = Some tt.
Definition set_WF{T}(enc:T->positive)(s:list T * PositiveMap.tree unit):Prop :=
forall (x:T),
set_in enc s x <->
In x (fst s).
Fixpoint pop_back{T}(x:T)(ls:list T):(list T) :=
match ls with
| h::t =>
x::(pop_back h t)
| nil => nil
end.

Lemma pop_back__nth_error{T} (h:T) t:
forall n:nat,
n<length t ->
nth_error (pop_back h t) n =
nth_error (h::t) n.