diff --git a/advanced.sage b/advanced.sage
new file mode 100644
index 0000000000000000000000000000000000000000..8ff4ad99913da96b8a99a03caed293de81c69ed3
--- /dev/null
+++ b/advanced.sage
@@ -0,0 +1,325 @@
+def Partitions(List):
+ """
+ Generates all proper partitions of List.
+ """
+ if len(List)==0:
+ yield []
+ return
+ if len(List)==1:
+ return
+
+ for A in Subsets( List[:-1] ):
+ if len(A) > 0:
+ M = List[:-1]
+ for a in A:
+ M.remove(a)
+ AA = A.list() + [List[-1]]
+ for r in Partitions(M):
+ yield r + [ AA ]
+# Partitions
+
+
+def Classes(Partition):
+ """
+ Returns a list determining the class
+ where the partition belongs.
+ """
+ m = max([ max(p) for p in Partition])
+ Res = range(m + 1)
+
+ for P in Partition:
+ m = min(P)
+ for p in P:
+ Res[p] = m
+
+ return Res
+# Classes
+
+
+def IsMinPartition(Part, Gamma):
+ """
+ Returns True if given partition is
+ lexicographically minimal in its class.
+ """
+ X = Classes(Part)
+
+ for r in [ GammaPartition(g, Part) for g in Gamma]:
+ x = Classes(r)
+ if x < X:
+ return False
+
+ return True
+# IsMinPartition
+
+
+def GammaPartition(Gamma, Partition):
+ """
+ Applies permutation Gamma on Partition.
+ """
+ Res = Set([])
+
+ for P in Partition:
+ P_ = Set([Gamma[r]-1 for r in P])
+ Res = Res.union(Set([P_]))
+
+ return Res
+# GammaPartition
+
+
+def PartitionClasses(Partitions, Gamma):
+ """
+ Returns list of classes of partitions.
+ """
+ Res = []
+ for Partition in Partitions:
+ if IsMinPartition(Partition, Gamma):
+ Res += [ Set([ GammaPartition(g, Partition) for g in Gamma ]) ]
+
+ return Res
+# PartitionClasses
+
+
+def NTuples(n):
+ """
+ Generates all n-tuples of {1, 2, 3, 4}^n.
+ """
+ if n==0:
+ yield []
+ return
+
+ for t in NTuples(n-1):
+ for i in [1, 2, 3, 4]:
+ yield t + [i]
+# NTuples
+
+
+def CountTerminalValues(n):
+ """
+ Counts all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ return 0
+
+ Count = 0
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ Count += 1
+
+ return Count
+# CountTerminalValues
+
+
+def TerminalValues(n):
+ """
+ Generates all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ yield []
+ return
+
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ yield T + [-s]
+# TerminalValues
+
+
+def Compatibility(Partition, TerminalValues):
+ """
+ Returns 1 if the partition is compatible with
+ values on terminals.
+ """
+ for Class in Partition:
+ s = Integers(5)(0)
+ for Index in Class:
+ s += TerminalValues[Index]
+ if s!=0:
+ return 0
+
+ return 1
+# Compatibility
+
+
+def Chi(PartitionClasses, TerminalValues):
+ """
+ Returns the vector of compatibility.
+ """
+ return [sum(Compatibility(P, TerminalValues) for P in Part) for Part in PartitionClasses]
+# Chi
+
+
+def IsFlow(TerminalValues):
+ """
+ Returns True if there exists a flow
+ with given values on terminals.
+ """
+ val = [ Integers(5)(i) for i in range(1,5) ]
+ for Val in TerminalValues:
+ val = [ v + Val for v in val if v + Val > 0 ]
+
+ return len(val) > 0
+# IsFlow
+
+
+def EncodeTerminalValues(Values):
+ """
+ Encodes values of terminals into one number.
+ """
+ if len(Values) == 1:
+ return Integer(Values[-1] - 1)
+
+ return 4 * EncodeTerminalValues(Values[:-1]) + Integer(Values[-1] - 1)
+# EncodeTerminalValues
+
+
+def GammaValues(Values, Gamma):
+ """
+ Applies permutation Gamma on Values.
+ """
+ Res = []
+ for i in range(len(Values)):
+ Res += [ Values[Gamma[i] - 1] ]
+
+ s = 1/Integers(5)(Res[0])
+ if s != 1:
+ return [ i * s for i in Res]
+
+ return Res
+# GammaValues
+
+
+def Generate(n, Buffer, Verbose, Save=True, Type=3):
+ """
+ Generates the matrices M_n and M'_n and
+ counts their ranks.
+ If some matrix is too long the rank is computed
+ by parts with matrix buffer of given size.
+
+ The parameter Verbose determines the number
+ of rows after that a progress message is printed.
+ The parameter Save determines whether the result
+ matrices are saved on disk.
+ The parameter Type determines which matrices
+ are generated: 1 - M_n, 2 - M'_n, 3 - both.
+ """
+ from datetime import datetime
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "initiating..."
+
+ G = DihedralGroup(n)
+ Gamma = [ g.tuple() for g in G ]
+
+ PartCls = PartitionClasses(Partitions(range(n)), Gamma)
+ PartSml = [ range(n-2), [ n-2, n-1 ] ]
+
+ Count = CountTerminalValues(n)
+ Vals = TerminalValues(n)
+
+ Used = []
+ for i in range(4^(n-1)):
+ Used += [ False ]
+
+ Mn = []
+ MMn = []
+ rn = 0
+ rrn = 0
+ proc = 0
+ verb = 0
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values..."
+
+ for H in Vals:
+ proc += 1
+ verb += 1
+
+ if verb >= Verbose:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ verb = 0
+
+ if Used[EncodeTerminalValues(H)]:
+ continue
+
+ Used[EncodeTerminalValues(H)] = True
+
+ if IsFlow(H):
+ X = Chi(PartCls, H)
+ for G in Gamma:
+ Used[EncodeTerminalValues(GammaValues(H, G))] = True
+
+ if Type & 1 == 1:
+ Mn += [ X ]
+ rn += 1
+ if rn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn overflow (", rn, ")..."
+ M = Matrix(QQ, Mn)
+ rn = M.rank()
+ P, L, U = M.LU()
+ Mn = [ U[i].list() for i in range(rn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn completed (", rn, ")"
+
+ if Type & 2 == 2:
+ MMn += [ X ]
+ rrn += 1
+ if rrn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn overflow (", rrn, ")..."
+ M = Matrix(QQ, MMn)
+ rrn = M.rank()
+ P, L, U = M.LU()
+ MMn = [ U[i].list() for i in range(rrn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn completed (", rrn, ")"
+
+ continue
+
+ if (Compatibility(PartSml, H) == 1) and IsFlow(H[:-2]):
+ X = Chi(PartCls, H)
+ for G in Gamma:
+ Used[EncodeTerminalValues(GammaValues(H, G))] = True
+
+ if Type & 2 == 2:
+ MMn += [ X ]
+ rrn += 1
+ if rrn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn overflow (", rrn, ")..."
+ M = Matrix(QQ, MMn)
+ rrn = M.rank()
+ P, L, U = M.LU()
+ MMn = [ U[i].list() for i in range(rrn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn completed (", rrn, ")"
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values completed"
+
+ Mn = Matrix(Mn)
+ MMn = Matrix(MMn)
+
+ if Save:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "saving the matrices..."
+
+ s = "saves/advanced/" + datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + "_" + n.str() + "_"
+ if Type & 1 == 1:
+ save(Mn, s + "1")
+ if Type & 2 == 2:
+ save(MMn, s + "2")
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks..."
+
+ rn = Mn.rank()
+ rrn = MMn.rank()
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks completed"
+
+ return [ n, rn, rrn ]
+# Generate
diff --git a/basic.sage b/basic.sage
new file mode 100644
index 0000000000000000000000000000000000000000..02250c9c991a0ebe92f455ae97811bef640e6ec7
--- /dev/null
+++ b/basic.sage
@@ -0,0 +1,205 @@
+def Partitions(List):
+ """
+ Generates all proper partitions of List.
+ """
+ if len(List)==0:
+ return [ [] ]
+ if len(List)==1:
+ return [ ]
+
+ Res = []
+
+ for A in Subsets( List[:-1] ):
+ if len(A)>0:
+ M = List[:-1]
+ for a in A:
+ M.remove(a)
+ AA = A.list() + [List[-1]]
+ Res += [ r + [ AA ] for r in Partitions(M) ]
+
+ return Res
+# Partitions
+
+
+def NTuples(n):
+ """
+ Generates all n-tuples of {1, 2, 3, 4}^n.
+ """
+ if n==0:
+ yield []
+ return
+
+ for t in NTuples(n-1):
+ for i in [1, 2, 3, 4]:
+ yield t + [i]
+# NTuples
+
+
+def CountTerminalValues(n):
+ """
+ Counts all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ return 0
+
+ Count = 0
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ Count += 1
+
+ return Count
+# CountTerminalValues
+
+
+def TerminalValues(n):
+ """
+ Generates all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ yield []
+ return
+
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ yield T + [-s]
+# TerminalValues
+
+
+def Compatibility(Partition, TerminalValues):
+ """
+ Returns 1 if the partition is compatible with
+ values on terminals.
+ """
+ for Class in Partition:
+ s = Integers(5)(0)
+ for Index in Class:
+ s += TerminalValues[Index]
+ if s!=0:
+ return 0
+
+ return 1
+# Compatibility
+
+
+def Chi(Partitions, TerminalValues):
+ """
+ Returns the vector of compatibility.
+ """
+ return [Compatibility(P, TerminalValues) for P in Partitions]
+# Chi
+
+
+def IsFlow(TerminalValues):
+ """
+ Returns True if there exists a flow
+ with given values on terminals.
+ """
+ val = [ Integers(5)(i) for i in range(1,5) ]
+ for Val in TerminalValues:
+ val = [ v + Val for v in val if v + Val > 0 ]
+
+ return len(val) > 0
+# IsFlow
+
+
+def Generate(n, Buffer, Verbose, Save=True, Type=3):
+ """
+ Generates the matrices M_n and M_{C_n} and
+ counts their ranks.
+ If some matrix is too long the rank is computed
+ by parts with matrix buffer of given size.
+
+ The parameter Verbose determines the number
+ of rows after that a progress message is printed.
+ The parameter Save determines whether the result
+ matrices are saved on disk.
+ The parameter Type determines which matrices
+ are generated: 1 - M_n, 2 - M_{C_n}, 3 - both.
+ """
+ from datetime import datetime
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "initiating..."
+
+ Count = CountTerminalValues(n)
+ Parts = Partitions(range(n))
+ Vals = TerminalValues(n)
+
+ Mn = []
+ MCn = []
+ rn = 0
+ rCn = 0
+ proc = 0
+ verb = 0
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values..."
+
+ for V in Vals:
+ proc += 1
+ verb += 1
+ chi = False
+ if Type & 1 == 1:
+ X = Chi(Parts, V)
+ chi = True
+ Mn += [ X ]
+ rn += 1
+ if rn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn overflow (", rn, ")..."
+ M = Matrix(QQ, Mn)
+ rn = M.rank()
+ P, L, U = M.LU()
+ Mn = [ U[i].list() for i in range(rn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn completed (", rn, ")"
+ if Type & 2 == 2:
+ if IsFlow(V):
+ if not chi:
+ X = Chi(Parts, V)
+ MCn += [ X ]
+ rCn += 1
+ if rCn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MCn overflow (", rCn, ")..."
+ M = Matrix(QQ, MCn)
+ rCn = M.rank()
+ P, L, U = M.LU()
+ MCn = [ U[i].list() for i in range(rCn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MCn completed (", rCn, ")"
+ if verb >= Verbose:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ verb = 0
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values completed"
+
+ Mn = Matrix(Mn)
+ MCn = Matrix(MCn)
+
+ if Save:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "saving the matrices..."
+
+ s = "saves/basic/" + datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + "_" + n.str() + "_"
+ if Type & 1 == 1:
+ save(Mn, s + "1")
+ if Type & 2 == 2:
+ save(MCn, s + "2")
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks..."
+
+ rn = Mn.rank()
+ rCn = MCn.rank()
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks completed"
+
+ return [ n, rn, rCn ]
+# Generate
diff --git a/pairs.sage b/pairs.sage
new file mode 100644
index 0000000000000000000000000000000000000000..90cab3627156c79c8353041ef031fbab8d9f4e1a
--- /dev/null
+++ b/pairs.sage
@@ -0,0 +1,345 @@
+def Partitions(List):
+ """
+ Generates all proper partitions of List.
+ """
+ if len(List)==0:
+ yield []
+ return
+ if len(List)==1:
+ return
+
+ for A in Subsets( List[:-1] ):
+ if len(A) > 0:
+ M = List[:-1]
+ for a in A:
+ M.remove(a)
+ AA = A.list() + [List[-1]]
+ for r in Partitions(M):
+ yield r + [ AA ]
+# Partitions
+
+
+def Classes(Partition):
+ """
+ Returns a list determining the class
+ where the partition belongs.
+ """
+ m = max([ max(p) for p in Partition])
+ Res = range(m + 1)
+
+ for P in Partition:
+ m = min(P)
+ for p in P:
+ Res[p] = m
+
+ return Res
+# Classes
+
+
+def IsMinPartition(Part, Gamma):
+ """
+ Returns True if given partition is
+ lexicographically minimal in its class.
+ """
+ X = Classes(Part)
+
+ for r in [ GammaPartition(g, Part) for g in Gamma]:
+ x = Classes(r)
+ if x < X:
+ return False
+
+ return True
+# IsMinPartition
+
+
+def GammaPartition(Gamma, Partition):
+ """
+ Applies permutation Gamma on Partition.
+ """
+ Res = Set([])
+
+ for P in Partition:
+ P_ = Set([Gamma[r]-1 for r in P])
+ Res = Res.union(Set([P_]))
+
+ return Res
+# GammaPartition
+
+
+def PartitionClasses(Partitions, Gamma):
+ """
+ Returns list of classes of partitions.
+ """
+ Res = []
+ for Partition in Partitions:
+ if IsMinPartition(Partition, Gamma):
+ Res += [ Set([ GammaPartition(g, Partition) for g in Gamma ]) ]
+
+ return Res
+# PartitionClasses
+
+
+def NTuples(n):
+ """
+ Generates all n-tuples of {1, 2, 3, 4}^n.
+ """
+ if n==0:
+ yield []
+ return
+
+ for t in NTuples(n-1):
+ for i in [1, 2, 3, 4]:
+ yield t + [i]
+# NTuples
+
+
+def CountTerminalValues(n):
+ """
+ Counts all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ return 0
+
+ Count = 0
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ Count += 1
+
+ return Count
+# CountTerminalValues
+
+
+def TerminalValues(n):
+ """
+ Generates all values of n terminals with
+ - first item = 1,
+ - sum of all items = 0.
+ """
+ if n<=1:
+ yield []
+ return
+
+ for t in NTuples(n-2):
+ T = [1] + t
+ s = Integers(5)(0)
+ for i in T:
+ s += i
+ if s!=0:
+ yield T + [-s]
+# TerminalValues
+
+
+def Compatibility(Partition, TerminalValues):
+ """
+ Returns 1 if the partition is compatible with
+ values on terminals.
+ """
+ for Class in Partition:
+ s = Integers(5)(0)
+ for Index in Class:
+ s += TerminalValues[Index]
+ if s!=0:
+ return 0
+
+ return 1
+# Compatibility
+
+
+def Chi(PartitionClasses, TerminalValues):
+ """
+ Returns the vector of compatibility.
+ """
+ return [sum(Compatibility(P, TerminalValues) for P in Part) for Part in PartitionClasses]
+# Chi
+
+
+def IsFlow(TerminalValues):
+ """
+ Returns True if there exists a flow
+ with given values on terminals.
+ """
+ val = [ Integers(5)(i) for i in range(1,5) ]
+ for Val in TerminalValues:
+ val = [ v + Val for v in val if v + Val > 0 ]
+
+ return len(val) > 0
+# IsFlow
+
+
+def EncodeTerminalValues(Values):
+ """
+ Encodes values of terminals into one number.
+ """
+ if len(Values) == 1:
+ return Integer(Values[-1] - 1)
+
+ return 4 * EncodeTerminalValues(Values[:-1]) + Integer(Values[-1] - 1)
+# EncodeTerminalValues
+
+
+def GammaValues(Values, Gamma):
+ """
+ Applies permutation Gamma on Values.
+ """
+ Res = []
+ for i in range(len(Values)):
+ Res += [ Values[Gamma[i] - 1] ]
+
+ s = 1/Integers(5)(Res[0])
+ if s != 1:
+ return [ i * s for i in Res]
+
+ return Res
+# GammaValues
+
+
+def IsMatching(TerminalValues):
+ """
+ Returns True if there exists a perfect matching
+ with given values of terminals.
+ """
+ l = len(TerminalValues)
+ if l == 0:
+ return True
+ if l == 1:
+ return False
+
+ x = Integers(5)(0)
+ for i in range(l-1):
+ if x + TerminalValues[i] + TerminalValues[i+1] == 0:
+ H = TerminalValues[:i] + TerminalValues[i+2:]
+ return IsMatching(H)
+ if x + TerminalValues[0] + TerminalValues[l-1] == 0:
+ return IsMatching(TerminalValues[1:l-2])
+ return False
+# IsMatching
+
+
+def Generate(n, Buffer, Verbose, Save=True, Type=3):
+ """
+ Generates the matrices M_n and M'_n and
+ counts their ranks.
+ If some matrix is too long the rank is computed
+ by parts with matrix buffer of given size.
+
+ The parameter Verbose determines the number
+ of rows after that a progress message is printed.
+ The parameter Save determines whether the result
+ matrices are saved on disk.
+ The parameter Type determines which matrices
+ are generated: 1 - M_n, 2 - M'_n, 3 - both.
+ """
+ from datetime import datetime
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "initiating..."
+
+ G = DihedralGroup(n)
+ Gamma = [ g.tuple() for g in G ]
+
+ PartCls = PartitionClasses(Partitions(range(n)), Gamma)
+
+ Count = CountTerminalValues(n)
+ Vals = TerminalValues(n)
+
+ Used = []
+ for i in range(4^(n-1)):
+ Used += [ False ]
+
+ Mn = []
+ MMn = []
+ rn = 0
+ rrn = 0
+ proc = 0
+ verb = 0
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values..."
+
+ for H in Vals:
+ proc += 1
+ verb += 1
+
+ if verb >= Verbose:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ verb = 0
+
+ if Used[EncodeTerminalValues(H)]:
+ continue
+
+ Used[EncodeTerminalValues(H)] = True
+ X = Chi(PartCls, H)
+
+ if IsFlow(H):
+ for G in Gamma:
+ Used[EncodeTerminalValues(GammaValues(H, G))] = True
+
+ if Type & 1 == 1:
+ Mn += [ X ]
+ rn += 1
+ if rn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn overflow (", rn, ")..."
+ M = Matrix(QQ, Mn)
+ rn = M.rank()
+ P, L, U = M.LU()
+ Mn = [ U[i].list() for i in range(rn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for Mn completed (", rn, ")"
+
+ if Type & 2 == 2:
+ MMn += [ X ]
+ rrn += 1
+ if rrn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn overflow (", rrn, ")..."
+ M = Matrix(QQ, MMn)
+ rrn = M.rank()
+ P, L, U = M.LU()
+ MMn = [ U[i].list() for i in range(rrn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn completed (", rrn, ")"
+
+ continue
+
+ if IsMatching(H):
+ for G in Gamma:
+ Used[EncodeTerminalValues(GammaValues(H, G))] = True
+
+ if Type & 2 == 2:
+ MMn += [ X ]
+ rrn += 1
+ if rrn >= Buffer:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processed", proc, "of", Count, "...", (100 * proc/Count).round(), "%"
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn overflow (", rrn, ")..."
+ M = Matrix(QQ, MMn)
+ rrn = M.rank()
+ P, L, U = M.LU()
+ MMn = [ U[i].list() for i in range(rrn) ]
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "buffer for MMn completed (", rrn, ")"
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "processing terminal values completed"
+
+ Mn = Matrix(Mn)
+ MMn = Matrix(MMn)
+
+ if Save:
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "saving the matrices..."
+
+ s = "saves/pairs/" + datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + "_" + n.str() + "_"
+ if Type & 1 == 1:
+ save(Mn, s + "1")
+ if Type & 2 == 2:
+ save(MMn, s + "2")
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks..."
+
+ rn = Mn.rank()
+ rrn = MMn.rank()
+
+ print datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "counting the ranks completed"
+
+ return [ n, rn, rrn ]
+# Generate