From d6d518b5b4d7d7cb1ed1d3fca0bb1cbf0e52c5b6 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Tue, 21 May 2024 17:21:09 +0100 Subject: [PATCH] fix correctness error in tiny_rope23.sml's ins function (to do with traverseing down the N3 case) --- .gitignore | 10 ++++++++++ bench.mlb | 12 ++++++++++++ tiny_rope.sml | 14 ++++++++++---- tiny_rope23.sml | 14 ++++++++++++-- utils.sml | 37 ++++++++++++++++++++++++++----------- 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 625cbc1..68d400c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,16 @@ /bench /bench.du /bench.ud +/bench23 /examples /examples.du /examples.ud + +/svelte.txt +/svelte23.txt +/rust.txt +/rust23.txt +/seph.txt +/seph23.txt +/automerge.txt +/automerge23.txt diff --git a/bench.mlb b/bench.mlb index 82b749b..c82f437 100644 --- a/bench.mlb +++ b/bench.mlb @@ -1,5 +1,17 @@ $(SML_LIB)/basis/basis.mlb +ann + "allowVectorExps true" +in + svelte.sml + rust.sml + seph.sml + automerge.sml +end + tiny_rope.sml rope.sml + +tiny_rope23.sml + utils.sml diff --git a/tiny_rope.sml b/tiny_rope.sml index 64b08bd..dbac9b4 100644 --- a/tiny_rope.sml +++ b/tiny_rope.sml @@ -7,7 +7,7 @@ sig val insert: int * string * t -> t val append: string * t -> t val delete: int * int * t -> t - val toString: t -> string list + val toString: t -> string val foldFromIdxTerm: (char * 'a -> 'a) * ('a -> bool) * int * t * 'a -> 'a val foldFromIdx: (char * 'a -> 'a) * int * t * 'a -> 'a end @@ -33,9 +33,15 @@ struct | N0 s => f (state, s) | _ => raise AuxConstructor - fun toStringFolder (acc, str) = str :: acc - fun toString rope = - foldr (toStringFolder, [], rope) + local + fun toListFolder (acc, str) = str :: acc + fun toList rope = foldr (toListFolder, [], rope) + in + fun toString rope = + let val lst = toList rope + in String.concat lst + end + end datatype balance = AddedNode | DeletedNode | NoAction diff --git a/tiny_rope23.sml b/tiny_rope23.sml index 2e5f455..c1d0e0d 100644 --- a/tiny_rope23.sml +++ b/tiny_rope23.sml @@ -30,6 +30,16 @@ struct foldr f state l end + local + fun toListFolder (str, lst) = str :: lst + fun toList rope = + foldr toListFolder [] rope + in + fun toString rope = + let val lst = toList rope + in String.concat lst + end + end (* Type used for balancing ropes, used only internally. *) datatype treeI = @@ -133,7 +143,7 @@ struct * Ropes don't usually have N3 nodes so the way we accomodate this is: * If current index is less than left metadata, use same strategy as * recursing to the left as N2 nodes. - * Else if current index is less than middle metadata, + * Else if current index is less than (left + middle) metadata, * recurse to middle node while subtracting left metadata. * Else, recurse to right node while subtracting (left metadata + * middle metadata). @@ -148,7 +158,7 @@ struct TI (l, lm) => TI (N3 (l, lm, m, mm, r, rm), lm + mm + rm) | OF (l1, lm1, l2, lm2) => OF (N2 (l1, lm1, l2, lm2), lm1 + lm2, N2 (m, mm, r, rm), mm + rm)) - else if curIdx < mm then + else if curIdx < (lm + mm) then (case ins (curIdx - lm, newStr, m) of TI (m, mm) => TI (N3 (l, lm, m, mm, r, rm), lm + mm + rm) | OF (m1, mm1, m2, mm2) => diff --git a/utils.sml b/utils.sml index 670db21..639bc0b 100644 --- a/utils.sml +++ b/utils.sml @@ -19,20 +19,19 @@ fun runTxns arr = Vector.foldl (fn ((pos, delNum, insStr), rope) => let - val rope = if delNum > 0 then Rope.delete (pos, delNum, rope) else rope val strSize = String.size insStr val rope = - if strSize > 0 then Rope.insert (pos, insStr, rope) else rope + if strSize > 0 then TinyRope23.insert (pos, insStr, rope) else rope in rope - end) Rope.empty arr + end) TinyRope23.empty arr fun runTxnsTime title arr = let val f = (fn () => runTxns arr) in timeFun title f end -fun runToString rope = Rope.toString rope +fun runToString rope = TinyRope23.toString rope fun runToStringTime title rope = let val f = (fn () => runToString rope) @@ -74,9 +73,20 @@ fun writeFile filename acc = () end +fun write (fileName, rope) = + let + val str = TinyRope23.toString rope + val io = TextIO.openOut fileName + val _ = TextIO.output (io, str) + val _ = TextIO.closeOut io + in + () + end + fun main () = let (* Timing benchmarks. *) + val startTime = LargeInt.fromInt 0 val _ = runTxns1000Times (999, svelte_arr, startTime) val _ = runTxns1000Times (999, rust_arr, startTime) val _ = runTxns1000Times (999, seph_arr, startTime) @@ -84,16 +94,21 @@ fun main () = (* Tests that line metadata is correct; will fail if incorrect. *) val svelte = runTxns svelte_arr - val _ = Rope.verifyLines svelte - val rust = runTxns rust_arr - val _ = Rope.verifyLines rust - val seph = runTxns seph_arr - val _ = Rope.verifyLines seph - val automerge = runTxns automerge_arr - val _ = Rope.verifyLines automerge + + (* + val _ = Rope.verifyLines svelte + val _ = Rope.verifyLines rust + val _ = Rope.verifyLines seph + val _ = Rope.verifyLines automerge + *) + + val _ = write ("svelte23.txt", svelte) + val _ = write ("rust23.txt", rust) + val _ = write ("seph23.txt", seph) + val _ = write ("automerge23.txt", automerge) in () end