 public struct KhChainSummand: Equatable, CustomStringConvertible {
     public let link: Link
     public let state: LinkSpliceState
+    public let components: [Link.Component]
     public let basis: [KhTensorElement]
     public let shifted: Int
     
     public init(link L: Link, state: LinkSpliceState, shifted: Int = 0) {
         let spliced = L.spliced(by: state)
-        let basis = KhChainSummand.generate(state: state, power: spliced.components)
-        self.init(link: spliced, state: state, basis: basis, shifted: shifted)
-    }
-    
-    internal init(link: Link, state: LinkSpliceState, basis: [KhTensorElement], shifted: Int) {
-        self.link = link
+        let comps = spliced.components
+        let basis = KhChainSummand.generate(state: state, power: comps.count)
+        
+        self.link = spliced
         self.state = state
+        self.components = comps
         self.basis = basis
         self.shifted = shifted
-    }
-    
-    public func shift(_ n: Int) -> KhChainSummand {
-        return KhChainSummand(link: link, state: state, basis: basis, shifted: shifted + n)
     }
     
     internal static func generate(state: LinkSpliceState, power n: Int) -> [KhTensorElement] {

    
    public var description: String {
        let n = Int( log2( Double(basis.count) ) )
        return Format.term(1, "A", n) + (shifted != 0 ? "{\(shifted)}" : "")
    }
}


    
    public var degree: Int {
        return factors.sum{ e in e.degree }
    }
    
    public static func ==(b1: KhTensorElement, b2: KhTensorElement) -> Bool {
