+
+// We will only build permutations with 0 or 1 elements in each of the left and
+// right sets. This covers all the reduced form permutations. Any longer
+// permutations will be similar to one of the reduced forms.
+func permuteExistingNumbers(generation int, universe surrealUniverse) []surrealNumber {
+ var numbers []surrealNumber
+
+ // First build permutations with 1 element in each set.
+ for i := 0; i < universe.cardinality(); i++ {
+ for j := 0; j < universe.cardinality(); j++ {
+ var leftSet, rightSet surrealSet
+ leftSet.insert(universe.numbers[i])
+ rightSet.insert(universe.numbers[j])
+ newSurrealNumber := surrealNumber{surrealValue{&leftSet,&rightSet},surrealMetadata{0,generation}}
+ numbers = append(numbers, newSurrealNumber)
+ }
+ }
+ // Now build permutations with one empty set and one 1-element set.
+ for i := 0; i < universe.cardinality(); i++ {
+ var tempSet surrealSet
+ tempSet.insert(universe.numbers[i])
+ newSurrealNumber := surrealNumber{surrealValue{&tempSet,nil},surrealMetadata{0,generation}}
+ numbers = append(numbers, newSurrealNumber)
+ newSurrealNumber = surrealNumber{surrealValue{nil,&tempSet},surrealMetadata{0,generation}}
+ numbers = append(numbers, newSurrealNumber)
+ }
+
+ return numbers
+}
+
+func pruneInvalidNumbers(candidates []surrealNumber, universe surrealUniverse) []surrealNumber {
+ var numbers []surrealNumber
+ for i := 0; i < len(candidates); i++ {
+ if isValidSurrealNumber(candidates[i], universe) {
+ numbers = append(numbers, candidates[i])
+ }
+ }
+ return numbers
+}
+
+// Although a non-reduced-form number is technically valid, for the purposes of
+// this program we're declaring it invalid.
+func isValidSurrealNumber(candidate surrealNumber, universe surrealUniverse) bool {
+ // Is the number in reduced form per Definition 3?
+ if candidate.number.leftSet.cardinality() > 1 || candidate.number.rightSet.cardinality() > 1 {
+ return false
+ }
+
+ // Is the number valid per Axiom 1?
+ if candidate.number.leftSet != nil && candidate.number.rightSet != nil {
+ // TODO: This needs to be beefed up since <|> = <-1|1>.
+ if candidate.number.leftSet == candiate.number.rightSet {
+ return false
+ }
+ if !universe.lessThanOrEqual(candidate.number.leftSet[0], candidate.number.rightSet[0]) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func addNumbersToUniverse(numbers []surrealNumber, universe *surrealUniverse) {
+ for i := 0; i < len(numbers); i++ {
+ universe.insert(numbers[i])
+ }
+}
+