From 3f5812bef551ca21a84119cd9f02e5f08abb8bf8 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 15:40:33 -0500 Subject: [PATCH 01/10] Explicitly convert the bounds to Int. --- prototype/Doubt/SES.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 1031798b8..f1b441b02 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -21,7 +21,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free>! - matrix = Matrix(width: a.count + 1, height: b.count + 1) { i, j in + matrix = Matrix(width: Int(a.count.toIntMax() + 1), height: Int(b.count.toIntMax() + 1)) { i, j in // Some explanation is warranted: // // 1. `matrix` captures itself during construction, because each vertex in the edit graph depends on other vertices. This is safe, because a) `Matrix` populates its fields lazily, and b) vertices only depend on those vertices downwards and rightwards of them. From 38686fee20a746eadebcff02fc1adbf8bf5ecafc Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 15:45:19 -0500 Subject: [PATCH 02/10] `constructRowMajor` operates over a pair of ranges. --- prototype/Doubt/Matrix.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/prototype/Doubt/Matrix.swift b/prototype/Doubt/Matrix.swift index d77db2871..930b57911 100644 --- a/prototype/Doubt/Matrix.swift +++ b/prototype/Doubt/Matrix.swift @@ -5,7 +5,7 @@ /// Values are retrieved by subscripting with row/column indices. Out-of-bound indices produce `nil` values, rather than asserting. public struct Matrix { public init(width: Int, height: Int, compute: (Int, Int) -> A) { - self.init(width: width, height: height, values: constructRowMajor(width, height: height, forEach: { i, j in Memo { compute(i, j) } })) + self.init(width: width, height: height, values: constructRowMajor(0.. { } /// Constructs a row-major ordering of values produced with `forEach`. -private func constructRowMajor(width: Int, height: Int, @noescape forEach: (Int, Int) -> A) -> [A] { +private func constructRowMajor(across: Range, down: Range, @noescape forEach: (I, I) -> A) -> [A] { var values: [A] = [] - values.reserveCapacity(width * height) - for j in 0.. Date: Thu, 5 Nov 2015 15:45:30 -0500 Subject: [PATCH 03/10] Matrix can be constructed with a pair of ranges. --- prototype/Doubt/Matrix.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototype/Doubt/Matrix.swift b/prototype/Doubt/Matrix.swift index 930b57911..be3643436 100644 --- a/prototype/Doubt/Matrix.swift +++ b/prototype/Doubt/Matrix.swift @@ -8,6 +8,10 @@ public struct Matrix { self.init(width: width, height: height, values: constructRowMajor(0..(across: Range, down: Range, compute: (I, I) -> A) { + self.init(width: Int(across.count.toIntMax()), height: Int(down.count.toIntMax()), values: constructRowMajor(across, down: down, forEach: { i, j in Memo { compute(i, j) } })) + } + public let width: Int public let height: Int From fdfdeb0dbf0a921c3d75cd797a8ff98b90840c40 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 15:46:36 -0500 Subject: [PATCH 04/10] SES operates over a pair of ranges. --- prototype/Doubt/SES.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index f1b441b02..11c679423 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -21,7 +21,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free>! - matrix = Matrix(width: Int(a.count.toIntMax() + 1), height: Int(b.count.toIntMax() + 1)) { i, j in + matrix = Matrix(across: a.indices, down: b.indices) { i, j in // Some explanation is warranted: // // 1. `matrix` captures itself during construction, because each vertex in the edit graph depends on other vertices. This is safe, because a) `Matrix` populates its fields lazily, and b) vertices only depend on those vertices downwards and rightwards of them. From 217a2c5a50ef6171a7412626ebf94e532143cc64 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 15:51:15 -0500 Subject: [PATCH 05/10] Define Matrix over two ranges. --- prototype/Doubt/Matrix.swift | 32 +++++++++++++++----------------- prototype/Doubt/SES.swift | 2 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/prototype/Doubt/Matrix.swift b/prototype/Doubt/Matrix.swift index be3643436..9789d2bb7 100644 --- a/prototype/Doubt/Matrix.swift +++ b/prototype/Doubt/Matrix.swift @@ -3,38 +3,36 @@ /// These values are populated by a function from the coordinates of a given cell to the matrix’s element type. /// /// Values are retrieved by subscripting with row/column indices. Out-of-bound indices produce `nil` values, rather than asserting. -public struct Matrix { - public init(width: Int, height: Int, compute: (Int, Int) -> A) { - self.init(width: width, height: height, values: constructRowMajor(0.. { + public init(across: Range, down: Range, compute: (I, I) -> A) { + self.init(across: across, down: down, values: constructRowMajor(across, down: down, forEach: { i, j in Memo { compute(i, j) } })) } - public init(across: Range, down: Range, compute: (I, I) -> A) { - self.init(width: Int(across.count.toIntMax()), height: Int(down.count.toIntMax()), values: constructRowMajor(across, down: down, forEach: { i, j in Memo { compute(i, j) } })) - } - - public let width: Int - public let height: Int + public let across: Range + public let down: Range private let values: [Memo] - public subscript (i: Int, j: Int) -> Memo? { - guard i < width && j < height else { return nil } - return values[i + j * width] + public subscript (i: I, j: I) -> Memo? { + guard across.contains(i) && down.contains(j) else { return nil } + let i = across.startIndex.distanceTo(i) + let j = down.startIndex.distanceTo(j) + return values[Int((i + j * across.count).toIntMax())] } // MARK: Functor - public func map(transform: A -> Other) -> Matrix { - return Matrix(width: width, height: height, values: values.map { $0.map(transform) }) + public func map(transform: A -> Other) -> Matrix { + return Matrix(across: across, down: down, values: values.map { $0.map(transform) }) } // MARK: Implementation details - private init(width: Int, height: Int, values: [Memo]) { - self.width = width - self.height = height + private init(across: Range, down: Range, values: [Memo]) { + self.across = across + self.down = down self.values = values } } diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 11c679423..43938fe25 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -20,7 +20,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free>! + var matrix: Matrix, Int>! matrix = Matrix(across: a.indices, down: b.indices) { i, j in // Some explanation is warranted: // From 6a0068362e46ec9f57acf911f2622fd8ba054919 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 15:51:50 -0500 Subject: [PATCH 06/10] Subscript with the correct indices. --- prototype/Doubt/SES.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 43938fe25..5dd342ab2 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -62,7 +62,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free Date: Thu, 5 Nov 2015 15:52:38 -0500 Subject: [PATCH 07/10] Use successors rather than integer addition. --- prototype/Doubt/SES.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 5dd342ab2..78a28efb3 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -28,9 +28,9 @@ public func SES(a: [Term], _ b: [Term], cost: Free Date: Thu, 5 Nov 2015 16:04:39 -0500 Subject: [PATCH 08/10] Correct the Matrix sizing. --- prototype/Doubt/SES.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 78a28efb3..5970bda14 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -21,7 +21,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free, Int>! - matrix = Matrix(across: a.indices, down: b.indices) { i, j in + matrix = Matrix(across: a.startIndex.. Date: Thu, 5 Nov 2015 16:12:53 -0500 Subject: [PATCH 09/10] =?UTF-8?q?Don=E2=80=99t=20transpose=20the=20coordin?= =?UTF-8?q?ate=20system.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prototype/Doubt/Matrix.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prototype/Doubt/Matrix.swift b/prototype/Doubt/Matrix.swift index 9789d2bb7..5537729bd 100644 --- a/prototype/Doubt/Matrix.swift +++ b/prototype/Doubt/Matrix.swift @@ -41,8 +41,8 @@ public struct Matrix { private func constructRowMajor(across: Range, down: Range, @noescape forEach: (I, I) -> A) -> [A] { var values: [A] = [] values.reserveCapacity(Int(across.count.toIntMax()) * Int(down.count.toIntMax())) - for j in across { - for i in down { + for j in down { + for i in across { values.append(forEach(i, j)) } } From 84ed21b1a2681f6258a61fae5a84d05da4149707 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Thu, 5 Nov 2015 16:14:10 -0500 Subject: [PATCH 10/10] Generalize SES to arbitrary `CollectionType`. --- prototype/Doubt/SES.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prototype/Doubt/SES.swift b/prototype/Doubt/SES.swift index 5970bda14..d04c06ccd 100644 --- a/prototype/Doubt/SES.swift +++ b/prototype/Doubt/SES.swift @@ -1,8 +1,8 @@ /// Computes the SES (shortest edit script), i.e. the shortest sequence of diffs (`Free>`) for two arrays of `Term`s which would suffice to transform `a` into `b`. /// /// This is computed w.r.t. an `equals` function, which computes the equality of leaf nodes within terms, and a `recur` function, which produces diffs representing matched-up terms. -public func SES(a: [Term], _ b: [Term], cost: Free> -> Int, recur: (Term, Term) -> Free>?) -> [Free>] { - typealias Diff = Free> +public func SES(a: C, _ b: C, cost: Free> -> Int, recur: (C.Generator.Element, C.Generator.Element) -> Free>?) -> [Free>] { + typealias Diff = Free> if a.isEmpty { return b.map { .Insert($0) } } if b.isEmpty { return a.map { .Delete($0) } } @@ -20,7 +20,7 @@ public func SES(a: [Term], _ b: [Term], cost: Free, Int>! + var matrix: Matrix, C.Index>! matrix = Matrix(across: a.startIndex..