(*********************************************************************)


Fixpoint nweight (a : form) : nat :=
  match a with
  | Atom _ => 0
  | Falsum => 0
  | AndF a0 a1 => S (nweight a0 + nweight a1)
  | OrF a0 a1 => S (nweight a0 + nweight a1)
  | Imp a0 a1 => S (nweight a0 + nweight a1)
  end.(******************************************************************)




Definition nweight_work :=
  fold_right (fun (a : normal_form) (n : nat) => nweight (nf2form a) + n) 0.Remark nweight_work_app :
 forall bs work : nf_list,
 nweight_work (bs ++ work) = nweight_work bs + nweight_work work.Definition nweight_disj (d : disj) := nweight (disj2form d).Definition nweight_ds :=
  fold_right (fun (d : disj) (n : nat) => nweight_disj d + n) 0.Definition nweight_nestedimp (x : nested_imp) := nweight (nested_imp2form x).Definition nweight_ni :=
  fold_right (fun (x : nested_imp) (n : nat) => nweight_nestedimp x + n) 0.Definition nweight_decoratednestedimp (x : decorated_nested_imp) :=
  match x with
  | (x0, _) => nweight (nimp2form x0)
  end.Definition nweight_dni :=
  fold_right
    (fun (x : decorated_nested_imp) (n : nat) =>
     nweight_decoratednestedimp x + n) 0.Definition nweight_atomicimp (a : normal_form) := S (nweight (nf2form a)).Definition nweight_bs :=
  fold_right (fun (b : normal_form) (n : nat) => nweight_atomicimp b + n) 0.Definition nweight_ibs (x : Int * nf_list) :=
  match x with
  | (_, bs) => nweight_bs bs
  end.Definition nweight_ai (ai : atomic_imps) :=
  fold_right (fun (x : Int * nf_list) (n : nat) => nweight_ibs x + n) 0
    (LIN_AVL nf_list ai).(***************************************************************************)


Remark nweight_ai_perm :
 forall (l0 l1 : list (Int * nf_list)) (x : Int * nf_list),
 fold_right (fun (x : Int * nf_list) (n : nat) => nweight_ibs x + n) 0
   (l0 ++ x :: l1) =
 fold_right (fun (x : Int * nf_list) (n : nat) => nweight_ibs x + n) 0
   (x :: l0 ++ l1).Remark nweight_ai_ins :
 forall (i : Int) (b : normal_form) (ai ai' : atomic_imps),
 LIN_INS nf_list i (cons b) nf_nil ai ai' ->
 nweight (nf2form (AImp i b)) + nweight_ai ai = nweight_ai ai'.Remark nweight_ai_del :
 forall (i : Int) (bs : nf_list) (ai ai' : atomic_imps),
 REGULAR normal_form ai ->
 LOOKUP nf_list i ai bs ->
 LIN_DEL nf_list i bs ai ai' ->
 nweight_work bs + nweight_ai ai' < nweight_ai ai.(*********************************************************************)

Remark nweight_eqv_ni :
 forall ni1 ni2 : nested_imps,
 eqv_ni ni1 ni2 -> nweight_ni ni1 = nweight_ni ni2.Remark nweight_rev_app :
 forall (dni : decorated_nested_imps) (ni : nested_imps),
 nweight_ni ni + nweight_dni dni = nweight_ni (rev_app dni ni).(**********************************************************************)


Definition nweight_Sequent (work : nf_list) (ds : disjs) 
  (ni : nested_imps) (ai : atomic_imps) :=
  nweight_work work + (nweight_ds ds + (nweight_ni ni + nweight_ai ai)).

(* Specifications: *)
Lemma nweight_shift_work_ni0 : forall (x : nimp) (work : nf_list) (ds : disjs) (ni : nested_imps) (ai : atomic_imps), nweight_Sequent (NImp_NF x :: work) ds ni ai = nweight_Sequent work ds (Undecorated x :: ni) ai.
Lemma nweight_shift_work_ds : forall (i j : Int) (work : nf_list) (ds : disjs) (ni : nested_imps) (ai : atomic_imps), nweight_Sequent (NDisj i j :: work) ds ni ai = nweight_Sequent work ((i, j) :: ds) ni ai.
Lemma nweight_shift_work_ai : forall (i : Int) (b : normal_form) (work : nf_list) (ds : disjs) (ni : nested_imps) (ai ai' : atomic_imps), LIN_INS nf_list i (cons b) nf_nil ai ai' -> nweight_Sequent (AImp i b :: work) ds ni ai = nweight_Sequent work ds ni ai'.
Lemma nweight_shift_ai_work : forall (i : Int) (bs work : nf_list) (ds : disjs) (ni : nested_imps) (ai ai' : atomic_imps), LOOKUP nf_list i ai bs -> REGULAR normal_form ai -> LIN_DEL nf_list i bs ai ai' -> nweight_Sequent (bs ++ work) ds ni ai' < nweight_Sequent work ds ni ai.
Lemma nweight_sequent_eqv : forall (work : nf_list) (ds : disjs) (ni1 ni2 : nested_imps) (ai : atomic_imps), eqv_ni ni1 ni2 -> nweight_Sequent work ds ni1 ai = nweight_Sequent work ds ni2 ai.
Lemma nweight_sequent_nimp_left : forall (a0 a1 : Int) (b : normal_form) (work : nf_list) (ds : disjs) (ni1 ni2 : nested_imps) (dni1 : decorated_nested_imps) (ai : atomic_imps) (n : nat), eqv_ni (rev_app dni1 ni1) ni2 -> nweight_Sequent work ds (rev_app dni1 (Undecorated (NImp a0 a1 b) :: ni1)) ai < S n -> nweight_Sequent (AImp a1 b :: NAtom a0 :: work) ds ni2 ai < n.
Lemma nweight_sequent_nimp_right : forall (a0 a1 : Int) (b : normal_form) (work : nf_list) (ds : disjs) (ni1 ni2 : nested_imps) (dni1 : decorated_nested_imps) (ai : atomic_imps) (n : nat), eqv_ni (rev_app dni1 ni1) ni2 -> nweight_Sequent work ds (rev_app dni1 (Undecorated (NImp a0 a1 b) :: ni1)) ai < S n -> nweight_Sequent (b :: work) ds ni2 ai < n.
Lemma nweight_sequent_left_disj_left : forall (i j : Int) (work : nf_list) (ds : disjs) (ni1 ni2 : nested_imps) (ai : atomic_imps) (n : nat), eqv_ni ni1 ni2 -> nweight_Sequent work ((i, j) :: ds) ni1 ai < S n -> nweight_Sequent (NAtom i :: work) ds ni2 ai < n.
Lemma nweight_sequent_left_disj_right : forall (i j : Int) (work : nf_list) (ds : disjs) (ni1 ni2 : nested_imps) (ai : atomic_imps) (n : nat), eqv_ni ni1 ni2 -> nweight_Sequent work ((i, j) :: ds) ni1 ai < S n -> nweight_Sequent (NAtom j :: work) ds ni2 ai < n.