Load loadpath.
Require MSets.
Require Coq.Structures.Orders.
Require Coq.Structures.OrdersFacts.
Require Recdef.
Require Omega.
Definition list_bound {A: Type} (f: A -> Prop) (l: list A):=
Forall f l /\  NoDup l.
Definition vset := Ensemble var.
Definition expr_bound (n: vset) (e: expr) :=
match e with Nil => True | Var v => n v end.
Definition pure_bound (n: vset) (a : pure_atom) :=
match a with
| Eqv e e' => expr_bound n e /\ expr_bound n e'
end.
Definition space_bound (n: vset) (a: space_atom) :=
match a with
| Next e e' =>  expr_bound n e /\ expr_bound n e'
| Lseg e e' =>  expr_bound n e /\ expr_bound n e'
end.
Definition pures_bound n := list_bound (pure_bound n).
Definition spaces_bound n := list_bound (space_bound n).
Definition pures_bound' n := Forall (pure_bound n).
Definition spaces_bound' n := Forall (space_bound n).
Definition clause_bound' (n: vset)  (cl: clause) :=
match cl with
| PureClause pi pi' _ _ =>  pures_bound' n pi /\ pures_bound' n pi'
| PosSpaceClause pi pi' sigma =>
pures_bound' n pi /\ pures_bound' n pi'/\ spaces_bound' n sigma
| NegSpaceClause pi sigma pi' =>
pures_bound' n pi /\ pures_bound' n pi'/\ spaces_bound' n sigma
end.
Definition clause_bound (n: vset)  (cl: clause) :=
match cl with
| PureClause pi pi' _ _ =>  pures_bound n pi /\ pures_bound n pi'
| PosSpaceClause pi pi' sigma =>
pures_bound n pi /\ pures_bound n pi'/\ spaces_bound n sigma
| NegSpaceClause pi sigma pi' =>
pures_bound n pi /\ pures_bound n pi'/\ spaces_bound n sigma
end.
Definition var_upto (v: var): Ensemble var := fun x => Ile x v.
unfold pure_bound. destruct a.
split.
simpl.
apply expr_bound_more with (var_upto (freshmax_expr e)).
apply included_var_upto.  apply Ile_var_max1.
apply expr_bound_freshmax.
simpl.
apply expr_bound_more with (var_upto (freshmax_expr e0)).
apply included_var_upto.  apply Ile_var_max2.
apply expr_bound_freshmax.
Qed.

Lemma pures_bound_freshmax:
forall gamma,
pures_bound' (var_upto (freshmax_list freshmax_pure_atom gamma)) gamma.