+include "dama/russell_support.ma".
+include "models/q_copy.ma".
+(*
+definition rebase_spec ≝
+ λl1,l2:q_f.λp:q_f × q_f.
+ And3
+ (same_bases (bars (\fst p)) (bars (\snd p)))
+ (same_values l1 (\fst p))
+ (same_values l2 (\snd p)).
+
+inductive rebase_cases : list bar → list bar → (list bar) × (list bar) → Prop ≝
+| rb_fst_full : ∀b,h1,xs.
+ rebase_cases (〈b,h1〉::xs) [] 〈〈b,h1〉::xs,〈b,〈OQ,OQ〉〉::copy xs〉
+| rb_snd_full : ∀b,h1,ys.
+ rebase_cases [] (〈b,h1〉::ys) 〈〈b,〈OQ,OQ〉〉::copy ys,〈b,h1〉::ys〉
+| rb_all_full : ∀b,h1,h2,h3,h4,xs,ys,r1,r2.
+ \snd(\last ▭ (〈b,h1〉::xs)) = \snd(\last ▭ (〈b,h3〉::r1)) →
+ \snd(\last ▭ (〈b,h2〉::ys)) = \snd(\last ▭ (〈b,h4〉::r2)) →
+ rebase_cases (〈b,h1〉::xs) (〈b,h2〉::ys) 〈〈b,h3〉::r1,〈b,h4〉::r2〉
+| rb_all_full_l : ∀b1,b2,h1,h2,xs,ys,r1,r2.
+ \snd(\last ▭ (〈b1,h1〉::xs)) = \snd(\last ▭ (〈b1,h1〉::r1)) →
+ \snd(\last ▭ (〈b2,h2〉::ys)) = \snd(\last ▭ (〈b1,h2〉::r2)) →
+ b1 < b2 →
+ rebase_cases (〈b1,h1〉::xs) (〈b2,h2〉::ys) 〈〈b1,h1〉::r1,〈b1,〈OQ,OQ〉〉::r2〉
+| rb_all_full_r : ∀b1,b2,h1,h2,xs,ys,r1,r2.
+ \snd(\last ▭ (〈b1,h1〉::xs)) = \snd(\last ▭ (〈b2,h1〉::r1)) →
+ \snd(\last ▭ (〈b2,h2〉::ys)) = \snd(\last ▭ (〈b2,h2〉::r2)) →
+ b2 < b1 →
+ rebase_cases (〈b1,h1〉::xs) (〈b2,h2〉::ys) 〈〈b2,〈OQ,OQ〉〉::r1,〈b2,h2〉::r2〉
+| rb_all_empty : rebase_cases [] [] 〈[],[]〉.
+
+alias symbol "pi2" = "pair pi2".
+alias symbol "pi1" = "pair pi1".
+alias symbol "leq" = "natural 'less or equal to'".
+inductive rebase_spec_aux_p (l1, l2:list bar) (p:(list bar) × (list bar)) : Prop ≝
+| prove_rebase_spec_aux:
+ rebase_cases l1 l2 p →
+ (sorted q2_lt (\fst p)) →
+ (sorted q2_lt (\snd p)) →
+ (same_bases (\fst p) (\snd p)) →
+ (same_values_simpl l1 (\fst p)) →
+ (same_values_simpl l2 (\snd p)) →
+ rebase_spec_aux_p l1 l2 p.
+
+lemma aux_preserves_sorting:
+ ∀b,b3,l2,l3,w. rebase_cases l2 l3 w →
+ sorted q2_lt (b::l2) → sorted q2_lt (b3::l3) → \fst b3 = \fst b →
+ sorted q2_lt (\fst w) → sorted q2_lt (\snd w) →
+ same_bases (\fst w) (\snd w) →
+ sorted q2_lt (b :: \fst w).
+intros 6; cases H; simplify; intros; clear H;
+[ apply (sorted_cons q2_lt); [2:assumption] apply (inversion_sorted2 ??? H1);
+| apply (sorted_cons q2_lt); [2:assumption]
+ whd; rewrite < H3; apply (inversion_sorted2 ??? H2);
+| apply (sorted_cons q2_lt); [2:assumption] apply (inversion_sorted2 ??? H3);
+| apply (sorted_cons q2_lt); [2:assumption] apply (inversion_sorted2 ??? H4);
+| apply (sorted_cons q2_lt); [2:assumption]
+ whd; rewrite < H6; apply (inversion_sorted2 ??? H5);
+| apply (sorted_one q2_lt);]
+qed.
+
+lemma aux_preserves_sorting2:
+ ∀b,b3,l2,l3,w. rebase_cases l2 l3 w →
+ sorted q2_lt (b::l2) → sorted q2_lt (b3::l3) → \fst b3 = \fst b →
+ sorted q2_lt (\fst w) → sorted q2_lt (\snd w) → same_bases (\fst w) (\snd w) →
+ sorted q2_lt (b :: \snd w).
+intros 6; cases H; simplify; intros; clear H;
+[ apply (sorted_cons q2_lt); [2:assumption] apply (inversion_sorted2 ??? H1);
+| apply (sorted_cons q2_lt); [2:assumption]
+ whd; rewrite < H3; apply (inversion_sorted2 ??? H2);
+| apply (sorted_cons q2_lt); [2: assumption] apply (inversion_sorted2 ??? H3);
+| apply (sorted_cons q2_lt); [2: assumption] apply (inversion_sorted2 ??? H4);
+| apply (sorted_cons q2_lt); [2: assumption]
+ whd; rewrite < H6; apply (inversion_sorted2 ??? H5);
+| apply (sorted_one q2_lt);]
+qed.
+*)
+
+
+
+definition rebase_spec_aux ≝
+ λl1,l2
+ :list bar.λp:(list bar) × (list bar).
+ sorted q2_lt l1 → (\snd (\last ▭ l1) = 〈OQ,OQ〉) →
+ sorted q2_lt l2 → (\snd (\last ▭ l2) = 〈OQ,OQ〉) →
+ rebase_spec_aux_p l1 l2 p.
+
+alias symbol "lt" = "Q less than".
+alias symbol "Q" = "Rationals".
+axiom q_unlimited: ∀x:ℚ.∃y:ratio.x<Qpos y.
+axiom q_halving: ∀x,y:ℚ.∃z:ℚ.x<z ∧ z<y.
+alias symbol "not" = "logical not".
+axiom q_not_OQ_lt_Qneg: ∀r. ¬ (OQ < Qneg r).
+lemma same_values_unit_OQ:
+ ∀b1,b2,h1,l. OQ < b2 → b2 < b1 → sorted q2_lt (〈b1,h1〉::l) →
+ sorted q2_lt [〈b2,〈OQ,OQ〉〉] →
+ same_values_simpl (〈b1,h1〉::l) [〈b2,〈OQ,OQ〉〉] → h1 = 〈OQ,OQ〉.
+intros 5 (b1 b2 h1 l POS); cases l;
+[1: intros; cases (q_unlimited b1); cut (b2 < Qpos w); [2:apply (q_lt_trans ??? H H4);]
+ lapply (H3 H1 ? H2 ? w H4 Hcut) as K; simplify; [1,2: autobatch]
+ rewrite > (value_unit 〈b1,h1〉) in K;
+ rewrite > (value_unit 〈b2,〈OQ,OQ〉〉) in K; assumption;
+|2: intros; unfold in H3; lapply depth=0 (H3 H1 ? H2 ?) as K; [1,2:simplify; autobatch]
+ clear H3; cases (q_halving b1 (b1 + \fst p)) (w Pw); cases w in Pw; intros;
+ [cases (q_lt_le_incompat ?? POS); apply q_lt_to_le; cases H3;
+ apply (q_lt_trans ???? H4); assumption;
+ |3: elim H3; lapply (q_lt_trans ??? H H4); lapply (q_lt_trans ??? POS Hletin);
+ cases (q_not_OQ_lt_Qneg ? Hletin1);
+ | cases H3; lapply (K r);
+ [2: simplify; assumption
+ |3: simplify; apply (q_lt_trans ???? H4); assumption;
+ |rewrite > (value_head b1,h1 .. q) in Hletin;
+
+
+
+ (* MANCA che le basi sono positive,
+ poi con halving prendi tra b1 e \fst p e hai h1=OQ,OQ*)
+
+