Section ra_compiler_min.
Variables (n : nat) (f : recalg (S n)) (Hf : ra_compiler_stm f).
(* i p o m  input = <v>  [p,p+n[ : v  m+0 : 0,1,..., [m+1,m+n] : <v> m+n+1 : 0 (zero) m+n+2 : 0 (tmp)  i:  copy [p,p+n[ -> [m+1,n+m+1[ 9n+i:  erase  m 2+9n+i:  compile f ? m o zero 2+l1+9n+i:  DEC o sauter vers ? 3+l1+9n+i:  INC m 4+l1+9n+i:  DEC zero jmp (2+9n+i) 5+l1+9n+i:  copy m -> o 14+l1+9n+i:  efface [m,n+m]  *)
Variables (i p o m : nat)
(H1 : o < m)
(H2 : ~ p <= o < n + p)
(H3 : n + p <= m).
Notation zero := (1+n+m).
Notation tmp  := (2+n+m).
Local Definition min_Q1 :=
mm_multi_copy tmp zero n p (1+m) i
++ mm_erase m zero (9*n+i).
Notation Q1 := min_Q1.
Local Fact min_Q1_length : length Q1 = 2+9*n.
Local Fact min_Q2_0_progress v e :
(forall j, zero <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+1+m))
-> ⟦f⟧ (e⇢m##v) 0
-> exists e', (forall j, j <> o -> e'⇢j = e⇢j)
/\ e'⇢o = 0
/\ (s1,Q2) // (s1,e) -+> (length Q2+s1,e').
Local Fact min_Q2_S_progress x v e :
(forall j, zero <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+1+m))
-> ⟦f⟧ (e⇢m##v) (S x)
-> exists e', (forall j, j <> o -> j <> m -> e'⇢j = e⇢j)
/\ e'⇢o = x
/\ e'⇢m = S (e⇢m)
/\ (s1,Q2) // (s1,e) -+> (s1,e').
Local Fact min_Q2_progress_rec v e k :
(forall j, zero <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+1+m))
-> (forall i, i < k -> exists x, ⟦f⟧ (i+(e⇢m)##v) (S x))
-> exists e', (forall j, j <> o -> j <> m -> e'⇢j = e⇢j)
/\ e'⇢m = k+(e⇢m)
/\ (s1,Q2) // (s1,e) ->> (s1,e').
Local Fact min_Q2_compute_rev v e :
(forall j, zero <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+1+m))
-> (s1,Q2) // (s1,e) ↓
-> exists k, ⟦f⟧ (k+(e⇢m)##v) 0 /\ forall j, j < k -> exists x, ⟦f⟧ (j+(e⇢m)##v) (S x).
Local Fact min_Q2_progress v e k :
(forall j, zero <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+1+m))
-> e⇢m = 0
-> s_min ⟦f⟧ v k
-> exists e', (forall j, j <> o -> j <> m -> e'⇢j = e⇢j)
/\ e'⇢m = k
/\ (s1,Q2) // (s1,e) -+> (length Q2+s1,e').
Local Definition min_s4 := length Q1+length Q2+i.
Notation s4 := min_s4.
Local Definition min_Q4 :=
Q1 ++ Q2
++ mm_copy m o tmp zero s4
++ mm_multi_erase m zero (1+n) (9+s4).
Notation Q4 := min_Q4.
Local Fact min_Q4_progress v e x :
(forall j, m <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+p))
-> s_min ⟦f⟧ v x
-> exists e', (forall j, j <> o -> e'⇢j = e⇢j)
/\ e'⇢o = x
/\ (i,Q4) // (i,e) -+> (length Q4+i,e').
Local Fact min_Q4_terminates v e :
(forall j, m <= j -> e⇢j = 0)
-> (forall j, vec_pos v j = e⇢(pos2nat j+p))
-> (i,Q4) // (i,e) ↓
-> exists x, s_min ⟦f⟧ v x.
Fact ra_compiler_min : ra_compiler_spec (ra_min f) i p o m.
End ra_compiler_min.

Corollary ra_mm_env_simulator n (f : recalg n) :
{ P | forall v e,   (forall p, e⇢(pos2nat p) = vec_pos v p)
-> (forall j, n < j -> e⇢j = 0)
-> (forall x, ⟦f⟧ v x
-> exists e', e' ⋈ e⦃n⇠x⦄
/\ (1,P) // (1,e) ->> (1+length P,e'))
/\ ((1,P) // (1,e) ↓ -> ex (⟦f⟧ v)) }.