         self.bottomDegree = Swift.min(chain0.offset,    chain1.offset,    chain2.offset)
     }
     
+    internal func seqIndex(_ i: Int, _ n: Int) -> Int {
+        return chainType.descending ? (topDegree - n) * 3 + i : (n - bottomDegree) * 3 + i
+    }
+    
+    internal func gridIndex(_ k: Int) -> (Int, Int) {
+        let (i, j) = (k >= 0) ? (k % 3, k / 3) : (k % 3 + 3, k / 3 - 1)
+        return (i, chainType.descending ? topDegree - j : bottomDegree + j)
+    }
+    
     public subscript(i: Int, n: Int) -> Object {
         assert((0 ..< 3).contains(i))
         return H[i][n]
     }
     
-    public func arrow(_ i: Int) -> Arrow {
-        assert((0 ..< 3).contains(i))
-        return map[i]
+    public subscript(k: Int) -> Object {
+        return object(k)
     }
     
-    public func makeIterator() -> IndexingIterator<[Element]> {
-        return degrees.flatMap { n in
-            (0 ..< 3).map{ i in (H[i][n], map[i]) }
-        }.makeIterator()
+    public func object(_ k: Int) -> Object {
+        let (i, n) = gridIndex(k)
+        return H[i][n]
+    }
+    
+    public func arrow(_ k: Int) -> Arrow {
+        let i = gridIndex(k).0
+        return map[i]
     }
     
     internal var degrees: [Int] {

        }
    }
    
    public var description: String {
        return "\(H[0]) -> \(H[1]) -> \(H[2])"
    }

            : (bottomDegree ... topDegree).toArray()
    }
    
    public func assertExactness(at i: Int, _ n: Int, debug: Bool = false) {
        let k = seqIndex(i, n)
        let H1 = object(k)
        
        if H1.isTrivial {
            return
        }
        
        let (H0, H2) = (object(k - 1), object(k + 1))
        let (f0, f1) = (arrow(k - 1), arrow(k))
        
        debugLog(print: debug, "----------\nExactness at \(H[i])[\((n))]\n\(H0) -> \(H1) -> \(H2)\n----------")
        
        // Im ⊂ Ker
        for x in H0.generators {
