@ -720,61 +720,45 @@ let rec simp_extract agg off len =
simp_memory len e
simp_memory len e
(* ⟨n,a⟩[0,n ) ==> ⟨n,a⟩ *)
(* ⟨n,a⟩[0,n ) ==> ⟨n,a⟩ *)
| Ap2 ( Memory , n , _ ) when equal off zero && equal n len -> agg
| Ap2 ( Memory , n , _ ) when equal off zero && equal n len -> agg
(* ( α₀^…^αᵢ^…^αⱼ^… ) [0+n₀+…+nᵢ₋₁, nᵢ+…+nⱼ ) ==> αᵢ^…^αⱼ where nₓ ≡ |αₓ| *)
(* For ( α₀^α₁ ) [o,l ) there are 3 cases:
| ApN ( Concat , na1N ) ->
*
let n = Vector . length na1N in
* ⟨ .. . ⟩ ^ ⟨ .. . ⟩
(* invariant: oI = ∑ᵥ₌₀ⁱ⁻¹ nᵥ *)
* [ , )
let rec find_off oI i =
* o < o + l ≤ | α ₀ | : ( α ₀ ^ α ₁ ) [ o , l ) = = > α ₀ [ o , l ) ^ α ₁ [ 0 , 0 )
[ % Trace . call fun { pf } -> pf " o_0^%i = %a " i pp oI ]
*
;
* ⟨ .. . ⟩ ^ ⟨ .. . ⟩
( if i = n then Ap3 ( Extract , agg , off , len )
* [ , )
else
* o ≤ | α ₀ | < o + l : ( α ₀ ^ α ₁ ) [ o , l ) = = > α ₀ [ o , | α ₀ | - o ) ^ α ₁ [ 0 , l - ( | α ₀ | - o ) )
match Vector . get na1N i with
*
| Ap2 ( Memory , nI , _ ) | Ap3 ( Extract , _ , _ , nI ) -> (
* ⟨ .. . ⟩ ^ ⟨ .. . ⟩
match ( oI , off ) with
* [ , )
| Integer { data = y } , Integer { data = z } when Z . gt y z ->
* | α ₀ | ≤ o : ( α ₀ ^ α ₁ ) [ o , l ) = = > α ₀ [ o , 0 ) ^ α ₁ [ o - | α ₀ | , l )
Ap3 ( Extract , agg , off , len )
*
| _ when not ( equal oI off ) ->
* So in general :
find_off ( simp_add2 oI nI ) ( i + 1 )
*
| _ ->
* ( α ₀ ^ α ₁ ) [ o , l ) = = > α ₀ [ o , l ₀ ) ^ α ₁ [ o ₁ , l - l ₀ )
(* invariant: lIJ = ∑ᵥ₌ᵢʲ⁻¹ nᵥ *)
* where l ₀ = max 0 ( min l | α ₀ | - o )
let rec find_len lIJ j =
* o ₁ = max 0 o - | α ₀ |
[ % Trace . call fun { pf } -> pf " l_%i^%i = %a " i j pp lIJ ]
* )
;
| ApN ( Concat , na1N ) -> (
( if j = n then find_off ( simp_add2 oI nI ) ( i + 1 )
match len with
else
| Integer { data = l } ->
match Vector . get na1N j with
Vector . fold_map_until na1N ~ init : ( l , off )
| Ap2 ( Memory , nJ , _ ) | Ap3 ( Extract , _ , _ , nJ ) -> (
~ f : ( fun ( l , oI ) naI ->
let lIJ = simp_add2 lIJ nJ in
let nI = agg_size_exn naI in
match ( lIJ , len ) with
if Z . equal Z . zero l then
(* ( α₀^…^αᵢ^… ) [0+n₀+…+nᵢ₋₁, l ) ==> ( αᵢ^… ) [0,l )
Continue ( ( l , oI ) , simp_extract naI oI zero )
where n ₓ ≡ | α ₓ | * )
else
| Integer { data = y } , Integer { data = z }
let oI_nI = simp_sub oI nI in
when Z . gt y z ->
match oI_nI with
let naIN =
| Integer { data } ->
Vector . sub ~ pos : i ~ len : ( n - i ) na1N
let oJ = if Z . sign data < = 0 then zero else oI_nI in
in
let lI = Z . ( max zero ( min l ( neg data ) ) ) in
simp_extract ( simp_concat naIN ) zero len
let l = Z . ( l - lI ) in
| Integer { data = y } , Integer { data = z }
Continue ( ( l , oJ ) , simp_extract naI oI ( integer lI ) )
when Z . gt y z ->
| _ -> Stop ( Ap3 ( Extract , agg , off , len ) ) )
Ap3 ( Extract , agg , off , len )
~ finish : ( fun ( _ , e1N ) -> simp_concat e1N )
| _ when not ( equal lIJ len ) ->
| _ -> Ap3 ( Extract , agg , off , len ) )
find_len lIJ ( j + 1 )
| _ ->
let naIJ =
Vector . sub ~ pos : i ~ len : ( j - i + 1 ) na1N
in
simp_concat naIJ )
| _ -> violates invariant agg )
| >
[ % Trace . retn fun { pf } -> pf " %a " pp ]
in
find_len zero i )
| _ -> violates invariant agg )
| >
[ % Trace . retn fun { pf } -> pf " %a " pp ]
in
find_off zero 0
(* α [o,l ) *)
(* α [o,l ) *)
| _ -> Ap3 ( Extract , agg , off , len ) )
| _ -> Ap3 ( Extract , agg , off , len ) )
| >
| >