diff --git a/.idea/SetSolver1.iml b/.idea/SetSolver1.iml
index 9305f7a..e5841d2 100644
--- a/.idea/SetSolver1.iml
+++ b/.idea/SetSolver1.iml
@@ -8,6 +8,7 @@
+
diff --git a/README.md b/README.md
index 0f1006d..a5cd399 100644
--- a/README.md
+++ b/README.md
@@ -3,44 +3,52 @@ This script is solving set problems by brute-force. See [HOWTO](#HOWTO).
# HOWTO
Use python3.10 or newer. Download it [here](https://www.python.org/downloads/).
-```
+```shell
"python.exe" -m pip install SetSolver1
```
First import the module:
-```
+```python
import SetSolver1
```
Now you can use the method:
```
-SetSolver1.search(const_sets: dict[str, set[frozenset | int | tuple] | MathSet], result: set[frozenset | int | tuple] | MathSet, not_allowed: list = None, identity: Identity = None) -> list[MathSet] | None
+SetSolver1.search(const_dict: dict[str, set[frozenset | int | tuple] | MathSet] | ConstDictType,
+ result: set[frozenset | int | tuple] | MathSet | ResultType,
+ not_allowed: list[MODE] = None,
+ identity: RelationMathSet | None = None,
+ overflow: int = 30,
+ range_int: int = 20,
+ do_print: bool = True) -> ResultWay | None
```
-Where `const_sets` is a dictionary for the predefined constants and `result` is the wanted solution.
-With the method `search` you can find the probably shortest way to this solution by the predefined constants
-and normal set operations. With this method you will get a list of valid ways (mostly one way) back.
+Where `const_dict` is a dictionary for the predefined constants and `result` is the wanted solution.
+With the method `search` you can find probably the shortest way to this solution by the predefined constants
+and normal set operations. With this method you will get an ResultWay object back.
-Little example:
-```
+[little example](/examples/sets/exercice2.py):
+```python
import SetSolver1
# Here you set your predefined constants.
# Please make sure that you do not assign a variable letter twice.
# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {frozenset({2, frozenset()}), frozenset({5})},
- "B": {frozenset(), frozenset({3}), frozenset({5})}
-}
+const_dict = SetSolver1.SimpleMathSetConstDictType(
+ {
+ "A": {frozenset({2, frozenset()}), frozenset({5})}, # string "[[2, []],[5]]" is allowed too
+ "B": {frozenset(), frozenset({3}), frozenset({5})}
+ }
+)
# Here you set your wanted solution.
-result = {frozenset(), frozenset({3}), frozenset({5}), frozenset({frozenset()})}
+result = SetSolver1.SimpleMathSetResultType({frozenset(), frozenset({3}), frozenset({5}), frozenset({frozenset()})})
-output = SetSolver1.search(const_sets, result)
+output = SetSolver1.search(const_dict, result)
```
-
-See German examples [here](beispiele.md) with outputs.
+More examples are [here](/examples)
+See German examples explanation [here](beispiele.md) with outputs.
# Requirements
diff --git a/SetSolver1/MODE.py b/SetSolver1/MODE.py
index c1faed6..447234a 100644
--- a/SetSolver1/MODE.py
+++ b/SetSolver1/MODE.py
@@ -1,19 +1,164 @@
-# tuple of index, used_vars, priority
-UNION = 0, (1, 2), 1
-COMPLEMENT_X = 1, (1, 2), 1
-COMPLEMENT_Y = 2, (2, 1), 1
-INTERSECTION = 3, (1, 2), 2
-COMPOSITION_X = 4, (1, 2), 3
-COMPOSITION_Y = 5, (2, 1), 3
-POWER_SET_X = 6, (1,), 4
-POWER_SET_Y = 7, (2,), 4
-CONVERSE_RELATION_X = 8, (1,), 3
-CONVERSE_RELATION_Y = 9, (2,), 3
-REFLEXIVE_CLOSURE_X = 10, (1,), 2
-REFLEXIVE_CLOSURE_Y = 11, (2,), 2
-TRANSITIVE_CLOSURE_X = 12, (1,), 2
-TRANSITIVE_CLOSURE_Y = 13, (2,), 2
-
-CHOOSE_BY_INDEX = (UNION, COMPLEMENT_X, COMPLEMENT_Y, INTERSECTION, COMPOSITION_X, COMPOSITION_Y, POWER_SET_X,
- POWER_SET_Y, CONVERSE_RELATION_X, CONVERSE_RELATION_Y, REFLEXIVE_CLOSURE_X, REFLEXIVE_CLOSURE_Y,
- TRANSITIVE_CLOSURE_X, TRANSITIVE_CLOSURE_Y)
+#!/usr/bin/env python3
+# coding: utf-8
+
+
+class MODE:
+ _value: tuple[tuple[int], int, int]
+ _print_str: str
+
+ def __init__(self, used_vars, priority, is_commutative, print_str):
+ """
+ Constructor method
+ :type used_vars: tuple[int]
+ :type priority: int
+ :type is_commutative: int
+ :type print_str: str
+ """
+ self._value = (used_vars, priority, is_commutative)
+ self._print_str = print_str
+
+ def __getitem__(self, item):
+ """
+ __getitem__ method
+ :type item: int
+ :rtype: int | tuple
+ """
+ return self._value[item]
+
+ def __lt__(self, other):
+ if type(other) == self.__class__:
+ return self[1] < other[1]
+
+ def __repr__(self):
+ return list(GET_BY_KEY.keys())[list(GET_BY_KEY.values()).index(self)]
+
+ def format(self, x, y):
+ """
+ returns format _print_str with x and y
+ :type x: str
+ :type y: str
+ :rtype: str
+ """
+ return self._print_str.format(x=x, y=y)
+
+ def is_multi_mode(self):
+ return self[0] == (1, 2)
+
+ def is_single_mode(self):
+ return not self.is_multi_mode()
+
+
+CONST = MODE(
+ used_vars=tuple(),
+ priority=1,
+ is_commutative=1,
+ print_str='{x}'
+)
+IDENTITY = MODE(
+ used_vars=tuple(),
+ priority=1,
+ is_commutative=1,
+ print_str=''
+)
+TEMPORARY_CREATED = MODE(
+ used_vars=tuple(),
+ priority=1,
+ is_commutative=1,
+ print_str=''
+)
+UNION = MODE(
+ used_vars=(1, 2),
+ priority=1,
+ is_commutative=1,
+ print_str='({x}+{y})'
+)
+COMPLEMENT = MODE(
+ used_vars=(1, 2),
+ priority=1,
+ is_commutative=0,
+ print_str='({x}-{y})'
+)
+INTERSECTION = MODE(
+ used_vars=(1, 2),
+ priority=2,
+ is_commutative=1,
+ print_str='({x}&{y})'
+)
+COMPOSITION = MODE(
+ used_vars=(1, 2),
+ priority=3,
+ is_commutative=0,
+ print_str='({x}.{y})'
+)
+POWER_SET = MODE(
+ used_vars=(1,),
+ priority=4,
+ is_commutative=1,
+ print_str='pow({x})'
+)
+SYMMETRIC_DIFFERENCE = MODE(
+ used_vars=(1, 2),
+ priority=99, # TODO
+ is_commutative=1,
+ print_str='({x}sym{y})'
+)
+CONVERSE_RELATION = MODE(
+ used_vars=(1,),
+ priority=3,
+ is_commutative=1,
+ print_str='inverse({x})'
+)
+REFLEXIVE_CLOSURE = MODE(
+ used_vars=(1,),
+ priority=2,
+ is_commutative=1,
+ print_str='reflexive_cl({x})'
+)
+TRANSITIVE_CLOSURE = MODE(
+ used_vars=(1,),
+ priority=2,
+ is_commutative=1,
+ print_str='transitive_cl({x})'
+)
+MULTISET_DISJOINT_UNION = MODE(
+ used_vars=(1, 2),
+ priority=2,
+ is_commutative=1,
+ print_str='({x}+{y})'
+)
+MULTISET_DIFFERENCE = MODE(
+ used_vars=(1, 2),
+ priority=2,
+ is_commutative=0,
+ print_str='({x}-{y})'
+)
+
+GET_BY_KEY = {
+ "CONST": CONST,
+ "IDENTITY": IDENTITY,
+ "TEMPORARY_CREATED": TEMPORARY_CREATED,
+ "union": UNION,
+ "complement": COMPLEMENT,
+ "intersection": INTERSECTION,
+ "composition": COMPOSITION,
+ "power_set": POWER_SET,
+ "symmetric_difference": SYMMETRIC_DIFFERENCE,
+ "converse_relation": CONVERSE_RELATION,
+ "reflexive_closure": REFLEXIVE_CLOSURE,
+ "transitive_closure": TRANSITIVE_CLOSURE,
+ "disjoint_union": MULTISET_DISJOINT_UNION,
+ "multi_set_difference": MULTISET_DIFFERENCE
+}
+
+CHOOSE_BY_INDEX = [UNION, COMPLEMENT, INTERSECTION, COMPOSITION, POWER_SET, CONVERSE_RELATION, REFLEXIVE_CLOSURE,
+ TRANSITIVE_CLOSURE, MULTISET_DISJOINT_UNION, MULTISET_DIFFERENCE]
+SORTED_CHOOSE_BY_INDEX = sorted(CHOOSE_BY_INDEX)
+
+DEFAULT_NOT_ALLOWED = [COMPOSITION, CONVERSE_RELATION, REFLEXIVE_CLOSURE, TRANSITIVE_CLOSURE, MULTISET_DISJOINT_UNION,
+ MULTISET_DIFFERENCE]
+NOT_ALLOWED_EVERYTHING = CHOOSE_BY_INDEX
+
+RESULT = TEMPORARY_CREATED
+TEMPORARY_CREATED_WAY = (TEMPORARY_CREATED, None, None)
+CONST_WAY = (CONST, None, None)
+IDENTITY_WAY = (IDENTITY, None, None)
diff --git a/SetSolver1/MathSet.py b/SetSolver1/MathSet.py
new file mode 100644
index 0000000..8e8f561
--- /dev/null
+++ b/SetSolver1/MathSet.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from __future__ import annotations
+
+from SetSolver1.MODE import MODE, TEMPORARY_CREATED, CONST, CONST_WAY
+from SetSolver1.TinyMathSet import TinyMathSet
+
+
+class MathSet:
+ """
+ BaseClass BaseSet
+ """
+ def __init__(self, value, way):
+ """
+ Constructor method
+ :type value: any
+ :type way: (MODE, any, any)
+ """
+ self.value = value
+ self.way = way
+
+ def __repr__(self):
+ return "{0}({1})".format(type(self).__name__, self.__dict__)
+
+ def __str__(self):
+ return str(self.value)
+
+ def __hash__(self):
+ # Default: hash(x)==id(x)/16
+ # https://stackoverflow.com/a/11324771
+ # https://docs.python.org/3/glossary.html#term-hashable
+ return hash(self.value)
+
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.value == other.value
+ print("NotImplemented Equality Compare")
+ return NotImplemented
+
+ def __len__(self):
+ """
+ :rtype: int
+ """
+ return len(self.value)
+
+ def correct_way(self):
+ """
+ Helper method to set correct way to consts
+ """
+ if self.way == CONST_WAY:
+ self.way = (CONST, self, None)
+
+ def walk_way(self, going_by=None):
+ """
+ Walk through the way and count steps
+ :param going_by: value adding per step of way
+ :type going_by: int
+ :raises ValueError:
+ :return: steps of way
+ :rtype: int
+ """
+ mode = self.way[0]
+ if mode == TEMPORARY_CREATED:
+ raise ValueError("MODE.TEMPORARY_CREATED not allowed here")
+ if mode == CONST:
+ return 0
+ lt = list()
+ for i in mode[0]:
+ if self.way[i] is not None:
+ lt.append(self.way[i].walk_way(going_by))
+ return sum(lt) + (going_by if going_by is not None else mode[1])
+
+ def sort_key(self):
+ """
+ ascending order so: 2 is before 5
+ :rtype: (int, int)
+ """
+ # TODO ist there a way to sort by second key only if needed?
+ return self.walk_way(going_by=1), self.walk_way()
+
+ def deep_len(self):
+ return sum(el.deep_len() if type(el) == TinyMathSet else 1 for el in self.value)
+
+ def total_deep_len(self):
+ return sum(el.total_deep_len()+1 if type(el) == TinyMathSet else 1 for el in self.value)
+
+ def is_empty(self):
+ """
+ Is MathSet empty?
+ :rtype: bool
+ """
+ return len(self.value) == 0
+
+ def union(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def complement(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def intersection(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def power_set(self):
+ raise RuntimeError("this operation is not allowed")
+
+ def symmetric_difference(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def composition(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def converse_relation(self):
+ raise RuntimeError("this operation is not allowed")
+
+ def reflexive_closure(self):
+ raise RuntimeError("this operation is not allowed")
+
+ def transitive_closure(self):
+ raise RuntimeError("this operation is not allowed")
+
+ def disjoint_union(self, y):
+ raise RuntimeError("this operation is not allowed")
+
+ def multi_set_difference(self, y):
+ raise RuntimeError("this operation is not allowed")
diff --git a/SetSolver1/MultiMathSet.py b/SetSolver1/MultiMathSet.py
new file mode 100644
index 0000000..6af94c9
--- /dev/null
+++ b/SetSolver1/MultiMathSet.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from __future__ import annotations
+
+from SetSolver1.MathSet import MathSet
+from SetSolver1.MODE import MODE, GET_BY_KEY, CONST_WAY, RESULT
+from SetSolver1.helper.BaseTypes import ConstDictType, ResultType
+
+
+class MultiMathSet(MathSet):
+ """
+ Class MultiMathSet, inherit by 'BaseSet'
+ """
+ value: dict[str, int]
+ way: tuple[MODE, (MultiMathSet | None), (MultiMathSet | None)]
+
+ def __init__(self, value, way):
+ """
+ Constructor method
+ :type value: dict[str, int]
+ :type way: (MODE, MultiMathSet | None, MultiMathSet | None)
+ """
+ super().__init__(value, way)
+
+ def __hash__(self):
+ return hash(tuple(sorted(self.value.items())))
+
+ def is_empty(self):
+ """
+ Is MultiMathSet empty?
+ :rtype: bool
+ """
+ return self.value == dict()
+
+ def total_deep_len(self):
+ a = self.value.values()
+ return len(a) + sum(a)
+
+ def union(self, y):
+ """
+ German: Vereinigung
+ :type y: MultiMathSet
+ :rtype: MultiMathSet
+ """
+ copy = self.value.copy()
+ for y1 in y.value.keys():
+ if not y.value[y1] == 0:
+ copy[y1] = max(copy.get(y1, 0), y.value[y1])
+ return MultiMathSet(copy, (GET_BY_KEY[self.union.__name__], self, y))
+
+ def disjoint_union(self, y):
+ """
+ German: disjunkte Vereinigung
+ :type y: MultiMathSet
+ :rtype: MultiMathSet
+ """
+ copy = self.value.copy()
+ for y1 in y.value.keys():
+ if not y.value[y1] == 0:
+ copy[y1] = copy.get(y1, 0) + y.value[y1]
+ return MultiMathSet(copy, (GET_BY_KEY[self.disjoint_union.__name__], self, y))
+
+ def multi_set_difference(self, y):
+ """
+ German: Differenz
+ :type y: MultiMathSet
+ :rtype: MultiMathSet
+ """
+
+ copy = self.value.copy()
+ for y1 in y.value.keys():
+ if not y.value[y1] == 0 and y1 in copy.keys() and copy[y1] > y.value[y1]:
+ copy[y1] = copy[y1] - y.value[y1]
+ return MultiMathSet(copy, (GET_BY_KEY[self.multi_set_difference.__name__], self, y))
+
+ def intersection(self, y):
+ """
+ German: Schnitt
+ :type y: MultiMathSet
+ :rtype: MultiMathSet
+ """
+ copy = self.value.copy()
+ for y1 in set(copy.keys()).union(y.value.keys()):
+ copy[y1] = min(copy.get(y1, 0), y.value.get(y1, 0))
+ if copy[y1] == 0:
+ del copy[y1]
+ return MultiMathSet(copy, (GET_BY_KEY[self.intersection.__name__], self, y))
+
+
+class MultiMathSetConstDictType(ConstDictType):
+ def __init__(self, data):
+ """
+ :type data: dict[str, dict[str, int]]
+ :raises ValueError:
+ """
+ _const = dict()
+ for letter in data.keys():
+ for i in data[letter].values():
+ if i < 1: # check every int is not negative or 0
+ raise ValueError("no negative or zero value allowed in ConstDictType")
+ _const[letter] = MultiMathSet(data[letter], CONST_WAY)
+ _const[letter].correct_way()
+ super().__init__(_const)
+
+
+class MultiMathSetResultType(ResultType):
+ _result: MultiMathSet
+
+ def __init__(self, data):
+ """
+ :type data: dict[str, int]
+ """
+ super().__init__(MultiMathSet(data, RESULT))
diff --git a/SetSolver1/RelationMathSet.py b/SetSolver1/RelationMathSet.py
new file mode 100644
index 0000000..a0bfc29
--- /dev/null
+++ b/SetSolver1/RelationMathSet.py
@@ -0,0 +1,278 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from __future__ import annotations
+
+from SetSolver1.MODE import MODE, GET_BY_KEY, CONST_WAY, RESULT, IDENTITY_WAY
+from SetSolver1.SimpleMathSet import SimpleMathSet
+from SetSolver1.helper.BaseTypes import ConstDictType, ResultType
+
+
+class RelationMathSet(SimpleMathSet):
+ """
+ Class RelationMathSet, inherit by 'BaseSet'
+ """
+ value: frozenset[tuple[int | str, int | str]]
+ identity: RelationMathSet | None
+ way: tuple[MODE, (RelationMathSet | None), (RelationMathSet | None)]
+
+ def __init__(self, value, identity, way):
+ """
+ init RelationMathSet
+ :type value: frozenset[(int, int)] | collections.abc.Iterable[(int, int)]
+ :type identity: RelationMathSet | None
+ :type way: (MODE, RelationMathSet | None, RelationMathSet | None)
+ """
+ self.identity = identity
+ super().__init__(value, way)
+
+ def type_check(self, y):
+ """
+ Check if the type of MathSets is comparable
+ :type y: RelationMathSet
+ :raises TypeError:
+ """
+ if self.identity != y.identity:
+ raise TypeError("type_check error")
+
+ def is_identity(self, set_to_identity_of_itself=False):
+ """
+ :type set_to_identity_of_itself: bool
+ :rtype: RelationMathSet | bool
+ :raises ValueError:
+ """
+ if set_to_identity_of_itself:
+ if self.identity is not None:
+ raise ValueError("It is not allowed to change attribute value of this class")
+ self.identity = self
+ return self
+ else:
+ return self.identity == self
+
+ def union(self, y):
+ """
+ German: Vereinigungsmenge
+ :type y: RelationMathSet
+ :rtype: RelationMathSet
+ """
+ self.type_check(y)
+ copy = set(self.value)
+ copy.update(y.value)
+ return RelationMathSet(copy, self.identity, (GET_BY_KEY[self.union.__name__], self, y))
+
+ def complement(self, y):
+ """
+ German: Komplement - Subtraktion von Mengen
+ :type y: RelationMathSet
+ :rtype: RelationMathSet
+ """
+ self.type_check(y)
+ return RelationMathSet(self.value.difference(y.value), self.identity,
+ (GET_BY_KEY[self.complement.__name__], self, y))
+
+ def intersection(self, y):
+ """
+ German: Schnittmenge
+ :type y: RelationMathSet
+ :rtype: RelationMathSet
+ """
+ self.type_check(y)
+ return RelationMathSet(self.value.intersection(y.value), self.identity,
+ (GET_BY_KEY[self.intersection.__name__], self, y))
+
+ def symmetric_difference(self, y):
+ """
+ German: Symmetrische Differenz
+ :type y: RelationMathSet
+ :rtype: RelationMathSet
+ """
+ self.type_check(y)
+ return RelationMathSet(self.value.symmetric_difference(y.value), self.identity,
+ (GET_BY_KEY[self.symmetric_difference.__name__], self, y))
+
+ def composition(self, y):
+ """
+ TODO optimization
+ German: Verkettung
+ :type y: RelationMathSet
+ :rtype: RelationMathSet
+ """
+ self.type_check(y)
+ lst = list()
+ for x1 in self.value:
+ for y1 in y.value:
+ if x1[1] == y1[0]:
+ lst.append((x1[0], y1[1]))
+ return RelationMathSet(lst, self.identity, (GET_BY_KEY[self.composition.__name__], self, y))
+
+ def converse_relation(self):
+ """
+ TODO optimization
+ German: Inverse (Umkehrrelation)
+ :rtype: RelationMathSet
+ """
+ return RelationMathSet(((x1[1], x1[0]) for x1 in self.value), self.identity,
+ (GET_BY_KEY[self.converse_relation.__name__], self, None))
+
+ def reflexive_closure(self):
+ """
+ TODO optimization
+ German: Reflexive Hülle
+ :rtype: RelationMathSet
+ """
+ return RelationMathSet(list(self.value) + [(x3, x3) for x3 in set([x1[x2]
+ for x2 in range(2) for x1 in self.value])],
+ self.identity, (GET_BY_KEY[self.reflexive_closure.__name__], self, None))
+
+ def transitive_closure(self):
+ """
+ TODO optimization
+ German: Transitive Hülle
+ :rtype: RelationMathSet
+ """
+ return RelationMathSet(list(self.value) + [(x1[0], x2[1])
+ for x2 in self.value for x1 in self.value if x1[1] == x2[0]],
+ self.identity, (GET_BY_KEY[self.transitive_closure.__name__], self, None))
+
+ def is_reflexive(self):
+ """
+ :rtype: bool
+ """
+ if self.identity is None:
+ return self.value == self.reflexive_closure().value
+ return self.identity.is_subset(self)
+
+ def is_irreflexive(self):
+ """
+ :rtype: bool
+ """
+ if self.identity is None:
+ """
+ One-Line
+ return frozenset((x3, x3) for x3 in set([x1[x2] for x2 in range(2) for x1 in self.value])
+ if (x3, x3) in self.value) == frozenset()
+ """
+ for x1 in self.value:
+ if (x1[0], x1[0]) in self.value or (x1[1], x1[1]) in self.value:
+ return False
+ return True
+ return self.intersection(self.identity).is_empty()
+
+ def is_subset(self, y):
+ """
+ is_subset
+ :type y: RelationMathSet
+ :rtype: bool
+ """
+ # self.value.issubset(y.value)
+ self.type_check(y)
+ for x1 in self.value:
+ if x1 not in y.value:
+ return False
+ return True
+
+ def is_symmetric_relation(self):
+ """
+ :rtype: bool
+ """
+ return self.converse_relation().is_subset(self)
+
+ def is_asymmetric_relation(self):
+ """
+ :rtype: bool
+ """
+ return self.intersection(self.converse_relation()).is_empty()
+
+ def is_antisymmetric_relation(self):
+ """
+ :rtype: bool
+ """
+ if self.identity is None:
+ for x1 in self.value:
+ if x1[::-1] in self.value and not x1[0] == x1[1]:
+ return False
+ return True
+ return self.intersection(self.converse_relation()).is_subset(self.identity)
+
+ def is_transitive(self):
+ """
+ :rtype: bool
+ """
+ return self.value == self.transitive_closure().value
+
+ def is_preorder(self):
+ """
+ German: Quasiordnung
+ :return: bool
+ """
+ return self.is_reflexive() and self.is_transitive()
+
+ def is_equivalence_relation(self):
+ """
+ German: Äquivalenzrelation (symmetrische Quasiordnung)
+ :return: bool
+ """
+ return self.is_preorder() and self.is_symmetric_relation()
+
+ def is_non_strict_partial_order(self):
+ """
+ German: Halbordnung (partielle Ordnung)
+ :return: bool
+ """
+ return self.is_reflexive() and self.is_antisymmetric_relation() and self.is_transitive()
+
+ def is_strict_partial_order(self):
+ """
+ German: Strikte Ordnung
+ :return: bool
+ """
+ return self.is_irreflexive() and self.is_transitive() and self.is_asymmetric_relation()
+
+ def print_properties(self):
+ """
+ Print all properties of this set with relations
+ :return: None
+ """
+ print("is_reflexive: " + str(self.is_reflexive()))
+ print("is_irreflexive: " + str(self.is_irreflexive()))
+ print("is_symmetrisch: " + str(self.is_symmetric_relation()))
+ print("is_asymmetrisch: " + str(self.is_asymmetric_relation()))
+ print("is_antisymmetrisch: " + str(self.is_antisymmetric_relation()))
+ print("is_transitiv: " + str(self.is_transitive()))
+
+
+class RelationMathSetConstDictType(ConstDictType):
+ def __init__(self, data, identity=None):
+ """
+ :type data: dict[str, set[tuple]]
+ :type identity: RelationMathSet | None
+ :raises ValueError:
+ """
+ _const = dict()
+ for letter in data.keys():
+ _const[letter] = RelationMathSet(data[letter], identity, CONST_WAY)
+ _const[letter].correct_way()
+ super().__init__(_const)
+
+
+class RelationMathSetResultType(ResultType):
+ _result: RelationMathSet
+
+ def __init__(self, data, identity):
+ """
+ Constructor method
+ :type data: set[tuple]
+ :type identity: RelationMathSet | None
+ """
+ super().__init__(RelationMathSet(data, identity, RESULT))
+
+
+class RelationMathSetIdentityType(ResultType):
+ _result: RelationMathSet
+
+ def __init__(self, data):
+ """
+ Constructor method
+ :type data: set[(int, int)]
+ """
+ super().__init__(RelationMathSet(data, None, IDENTITY_WAY).is_identity(True))
diff --git a/SetSolver1/ResultWay.py b/SetSolver1/ResultWay.py
new file mode 100644
index 0000000..f87c146
--- /dev/null
+++ b/SetSolver1/ResultWay.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1.MathSet import MathSet
+from SetSolver1.helper.BaseTypes import ConstDictType
+
+
+class ResultWay:
+ def __init__(self, result, const_dict, reversed_const_dict, results):
+ """
+ Constructor method
+ :type result: MathSet
+ :type const_dict: dict[str, MathSet] | ConstDictType
+ :type reversed_const_dict: dict[MathSet, str]
+ :type results: set[MathSet]
+ """
+ self.result = result
+ self.const_dict = const_dict
+ self.reversed_const_dict = reversed_const_dict
+ self.results = results
+
+ def __repr__(self):
+ return str(self.result)
diff --git a/SetSolver1/STATUS.py b/SetSolver1/STATUS.py
deleted file mode 100644
index e62e793..0000000
--- a/SetSolver1/STATUS.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from enum import Enum
-
-
-class STATUS(Enum):
- CONST = 1
- NONE = 2
diff --git a/SetSolver1/SimpleMathSet.py b/SetSolver1/SimpleMathSet.py
new file mode 100644
index 0000000..02f7aa8
--- /dev/null
+++ b/SetSolver1/SimpleMathSet.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from __future__ import annotations
+
+from itertools import chain, combinations
+from SetSolver1.MathSet import MathSet
+from SetSolver1.MODE import MODE, GET_BY_KEY, CONST_WAY, RESULT
+from SetSolver1.TinyMathSet import TinyMathSet
+from SetSolver1.helper.BaseTypes import ConstDictType, ResultType
+from SetSolver1.helper.update import to_tiny_math_set
+
+
+class SimpleMathSet(MathSet):
+ """
+ Class SimpleMathSet, inherit by 'BaseSet'
+ """
+ value: frozenset[TinyMathSet | tuple | int | str]
+ way: tuple[MODE, (SimpleMathSet | None), (SimpleMathSet | None)]
+
+ def __init__(self, value, way):
+ """
+ init SimpleMathSet
+ :type value: frozenset[TinyMathSet | tuple | int | str] | collections.abc.Iterable[
+ TinyMathSet | tuple | int | str]
+ :type way: (MODE, SimpleMathSet | None, SimpleMathSet | None)
+ """
+ if type(value) != frozenset:
+ value = frozenset(value)
+ super().__init__(value, way)
+
+ def __str__(self):
+ if self.is_empty():
+ return "{}"
+ return str(set(self.value))
+
+ def is_empty(self):
+ """
+ Is SimpleMathSet empty?
+ :rtype: bool
+ """
+ return self.value == frozenset()
+
+ def union(self, y):
+ """
+ German: Vereinigungsmenge
+ :type y: SimpleMathSet
+ :rtype: SimpleMathSet
+ """
+ # self.value.union(y.value) # TODO ist faster?
+ copy = set(self.value)
+ copy.update(y.value)
+ return SimpleMathSet(copy, (GET_BY_KEY[self.union.__name__], self, y))
+
+ def complement(self, y):
+ """
+ German: Komplement - Subtraktion von Mengen
+ :type y: SimpleMathSet
+ :rtype: SimpleMathSet
+ """
+ return SimpleMathSet(self.value.difference(y.value), (GET_BY_KEY[self.complement.__name__], self, y))
+
+ def intersection(self, y):
+ """
+ German: Schnittmenge
+ :type y: SimpleMathSet
+ :rtype: SimpleMathSet
+ """
+ return SimpleMathSet(self.value.intersection(y.value), (GET_BY_KEY[self.intersection.__name__], self, y))
+
+ def power_set(self):
+ """
+ German: Potenzmenge
+ :rtype: SimpleMathSet
+ """
+ return SimpleMathSet(
+ [TinyMathSet(y) for y in chain.from_iterable(
+ combinations(self.value, i) for i in range(len(self) + 1))],
+ (GET_BY_KEY[self.power_set.__name__], self, None))
+
+ def symmetric_difference(self, y):
+ """
+ German: Symmetrische Differenz
+ :type y: SimpleMathSet
+ :rtype: SimpleMathSet
+ """
+ return SimpleMathSet(self.value.symmetric_difference(y.value),
+ (GET_BY_KEY[self.symmetric_difference.__name__], self, y))
+
+
+class SimpleMathSetConstDictType(ConstDictType):
+ def __init__(self, data):
+ """
+ :type data: dict[str, set[frozenset | int] | str]
+ :raises ValueError:
+ """
+ _const = dict()
+ for letter in data.keys():
+ if type(data[letter]) == str:
+ from ast import literal_eval
+ _const[letter] = SimpleMathSet(to_tiny_math_set(
+ literal_eval(data[letter].replace("{", "[").replace("}", "]"))
+ ), CONST_WAY)
+ else:
+ # _const[letter] = SimpleMathSet(data[letter], CONST_WAY)
+ _const[letter] = SimpleMathSet(to_tiny_math_set(data[letter]), CONST_WAY)
+ _const[letter].correct_way()
+ super().__init__(_const)
+
+
+class SimpleMathSetResultType(ResultType):
+ _result: SimpleMathSet
+
+ def __init__(self, data):
+ """
+ :type data: set[frozenset | int] | str
+ """
+ if type(data) == str:
+ from ast import literal_eval
+ super().__init__(SimpleMathSet(
+ to_tiny_math_set(literal_eval(data.replace("{", "[").replace("}", "]"))),
+ RESULT))
+ else:
+ super().__init__(SimpleMathSet(to_tiny_math_set(data), RESULT))
diff --git a/SetSolver1/TinyMathSet.py b/SetSolver1/TinyMathSet.py
new file mode 100644
index 0000000..cbad8d4
--- /dev/null
+++ b/SetSolver1/TinyMathSet.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+class TinyMathSet(frozenset):
+ _total_deep_len = None
+
+ def __repr__(self):
+ if self == frozenset():
+ return "{}"
+ return str(set(self))
+
+ def deep_len(self):
+ return sum(el.deep_len() if isinstance(el, TinyMathSet) else 1 for el in self)
+
+ def total_deep_len(self):
+ if self._total_deep_len is None:
+ self._total_deep_len = sum(el.total_deep_len()+1 if isinstance(el, TinyMathSet) else 1 for el in self)
+ return self._total_deep_len
diff --git a/SetSolver1/__init__.py b/SetSolver1/__init__.py
index c272704..bed73b7 100644
--- a/SetSolver1/__init__.py
+++ b/SetSolver1/__init__.py
@@ -1 +1,8 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
from .main import search
+from . import MODE
+from .SimpleMathSet import SimpleMathSetConstDictType, SimpleMathSetResultType
+from .RelationMathSet import RelationMathSetConstDictType, RelationMathSetResultType, RelationMathSetIdentityType
+from .MultiMathSet import MultiMathSetConstDictType, MultiMathSetResultType
diff --git a/SetSolver1/helper/BaseTypes.py b/SetSolver1/helper/BaseTypes.py
new file mode 100644
index 0000000..861e679
--- /dev/null
+++ b/SetSolver1/helper/BaseTypes.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1.MathSet import MathSet
+
+
+class ConstDictType(dict):
+ def __init__(self, data):
+ """
+ Constructor method
+ :type data: collections.abc.Mapping
+ """
+ super().__init__(data)
+
+
+class ResultType:
+ _result: MathSet
+
+ def __init__(self, data):
+ """
+ Constructor method
+ :type data: MathSet
+ """
+ self._result = data
+
+ def get(self):
+ return self._result
diff --git a/SetSolver1/helper/transformer.py b/SetSolver1/helper/transformer.py
new file mode 100644
index 0000000..dcc6a05
--- /dev/null
+++ b/SetSolver1/helper/transformer.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1.MODE import TEMPORARY_CREATED_WAY
+from SetSolver1.RelationMathSet import RelationMathSet
+
+
+def do(value):
+ """
+ German: Erstelle Relation aus Menge
+ :rtype: SimpleMathSet
+ """
+ items = list()
+ for x1 in value:
+ if type(x1) != int and type(x1) != str:
+ return None
+ else:
+ for x2 in value:
+ items.append((x1, x2))
+ return RelationMathSet(items, None, TEMPORARY_CREATED_WAY)
+
+
+def identity_relation(value):
+ """
+ Identity relation based on the binary relation
+ if there are missing values in the binary relation, they will miss in the Identity
+ You should not really use this
+ :rtype: RelationMathSet | None
+ """
+ items = list()
+ for x in value:
+ if type(x) != int and type(x) != str:
+ return None
+ else:
+ items.append((x, x))
+ id_relation = RelationMathSet(items, None, TEMPORARY_CREATED_WAY)
+ id_relation.is_identity(True)
+ return id_relation
diff --git a/SetSolver1/helper/update.py b/SetSolver1/helper/update.py
index 1077d34..1c65d85 100644
--- a/SetSolver1/helper/update.py
+++ b/SetSolver1/helper/update.py
@@ -1,16 +1,18 @@
-from SetSolver1.math_set import TinyMathSet
+#!/usr/bin/env python3
+# coding: utf-8
+from SetSolver1.TinyMathSet import TinyMathSet
-def to_tiny_math_set(set_of_frozenset_s):
+
+def to_tiny_math_set(data):
"""
helper method to update to 2021.11.3
- :type set_of_frozenset_s: set[frozenset | int | tuple] | frozenset | int | tuple
- :rtype: TinyMathSet | int | tuple
+ :type data: any
+ :rtype: TinyMathSet | any
"""
- if type(set_of_frozenset_s) == frozenset or type(set_of_frozenset_s) == set:
- items = list()
- for x1 in set_of_frozenset_s:
- items.append(to_tiny_math_set(x1))
- # print(items)
- return TinyMathSet(items)
- return set_of_frozenset_s
+ if type(data) == frozenset or type(data) == set or type(data) == list:
+ lst = list()
+ for x in data:
+ lst.append(to_tiny_math_set(x))
+ return TinyMathSet(lst)
+ return data
diff --git a/SetSolver1/main.py b/SetSolver1/main.py
index 865e81d..6b82127 100644
--- a/SetSolver1/main.py
+++ b/SetSolver1/main.py
@@ -1,226 +1,204 @@
-from itertools import combinations_with_replacement
-from SetSolver1.math_set import MathSet, Identity, STATUS
+#!/usr/bin/env python3
+# coding: utf-8
+
+from itertools import combinations_with_replacement, product, chain, compress
+from SetSolver1.SimpleMathSet import SimpleMathSet
+from SetSolver1.MODE import MODE, CHOOSE_BY_INDEX, RESULT, CONST_WAY
+import SetSolver1.MODE
import SetSolver1.helper.update
+from SetSolver1.helper.BaseTypes import ConstDictType, ResultType
+from SetSolver1.MathSet import MathSet
+from SetSolver1.RelationMathSet import RelationMathSet
+from SetSolver1.ResultWay import ResultWay
-def tools(t, x, y):
+def tools(t, x, y, overflow):
"""
- :type t: int
+ Switch tool by MODE t
+ For tool use variables x and y
+ :type t: MODE
:type x: MathSet
- :type y: MathSet
- :rtype: MathSet
+ :type y: MathSet | None
+ :type overflow: int
+ :rtype: MathSet | None
+ :raises ValueError:
"""
- way = (t, x, y)
- match t:
+ match CHOOSE_BY_INDEX.index(t):
case 0:
- return x.union(y, way)
+ return x.union(y)
case 1:
- return x.complement(y, way)
+ return x.complement(y)
case 2:
- return y.complement(x, way)
+ return x.intersection(y)
case 3:
- return x.intersection(y, way)
+ return x.composition(y)
case 4:
- return x.composition(y, way)
- case 5:
- return y.composition(x, way)
- case 6:
if x.total_deep_len() >= (overflow / 2):
- return MathSet(frozenset(), x.identity, way)
- return x.power_set(way)
- case 7:
- if y.total_deep_len() >= (overflow / 2):
- return MathSet(frozenset(), y.identity, way)
- return y.power_set(way)
- case 8:
- return x.converse_relation(way)
- case 9:
- return y.converse_relation(way)
- case 10:
- return x.reflexive_closure(way)
- case 11:
- return y.reflexive_closure(way)
- case 12:
- return x.transitive_closure(way)
- case 13:
- return y.transitive_closure(way)
- case _:
- raise ValueError("value not found")
-
-
-def s_tools(t, x, y):
- """
- :type t: int
- :type x: str
- :type y: str
- :rtype: str
- """
- print("way: " + str(t) + " " + str([x, y])) if DEBUG else None
- match t:
- case 0:
- return "("+x+"+"+y+")"
- case 1:
- return "("+x+"-"+y+")"
- case 2:
- return "("+y+"-"+x+")"
- case 3:
- return "("+x+"&"+y+")"
- case 4:
- return "("+x+"."+y+")"
+ return None
+ return x.power_set()
case 5:
- return "("+y+"."+x+")"
+ return x.converse_relation()
case 6:
- return "pow("+x+")"
+ return x.reflexive_closure()
case 7:
- return "pow("+y+")"
+ return x.transitive_closure()
case 8:
- return "inverse("+x+")"
+ return x.multi_set_difference(y)
case 9:
- return "inverse("+y+")"
- case 10:
- return "reflexive_cl("+x+")"
- case 11:
- return "reflexive_cl("+y+")"
- case 12:
- return "transitive_cl("+x+")"
- case 13:
- return "transitive_cl("+y+")"
+ return x.disjoint_union(y)
case _:
raise ValueError("value not found")
-def format_way_helper(operand, item, const_sets, results):
+def format_way_helper(operand, reversed_const_dict, results):
"""
+ Create a string for way by operand
:type operand: MathSet | None
- :type item: MathSet
- :type const_sets: dict[str, MathSet]
+ :type reversed_const_dict: dict[MathSet, str]
:type results: set[MathSet]
:rtype: str
+ :raises SyntaxError:
"""
if operand is None:
return ""
- elif operand in const_sets.values():
- return list(const_sets.keys())[list(const_sets.values()).index(operand)]
+ elif operand in reversed_const_dict:
+ return reversed_const_dict[operand]
else:
- for a in results:
- # TODO is this fastest?
- if operand == a:
- return format_way(a, const_sets, results)
- raise SyntaxError(item.way)
+ if operand in results:
+ for a in results:
+ if operand == a:
+ return format_way(a.way, reversed_const_dict, results)
+ raise SyntaxError()
-def format_way(item, const_sets, results):
+def format_way(way, reversed_const_dict, results):
"""
- :type item: MathSet
- :type const_sets: dict[str, MathSet]
+ make way printable
+ :type way: (MODE, (MathSet | None), (MathSet | None))
+ :type reversed_const_dict: dict[MathSet, str]
:type results: set[MathSet]
:rtype: str
+ :raises SyntaxError:
"""
- if item.way == STATUS.CONST:
- return list(const_sets.keys())[list(const_sets.values()).index(item)]
- operator, operand1, operand2 = item.way
- return s_tools(operator, format_way_helper(operand1, item, const_sets, results),
- format_way_helper(operand2, item, const_sets, results))
-
-
-def check_set(check, const_sets, results):
- """
- :type check: MathSet
- :type const_sets: dict[str, MathSet]
- :type results: set[MathSet]
- """
- if check.total_deep_len() <= overflow:
- results.add(check)
- print(format_way(check, const_sets, results) + " --> " + str(check)) if DEBUG else None
+ operator, operand1, operand2 = way
+ try:
+ way_string = operator.format(format_way_helper(operand1, reversed_const_dict, results),
+ format_way_helper(operand2, reversed_const_dict, results))
+ except SyntaxError:
+ raise SyntaxError(way)
+ return way_string
-def get_valid_results(const_sets, result, results, do_print):
+def found_result(reversed_const_dict, result, results, do_print):
"""
- :type const_sets: dict[str, MathSet]
+ search for 'result' in 'results'
+ if found return it else None
+ :type reversed_const_dict: dict[MathSet, str]
:type result: MathSet
:type results: set[MathSet]
:type do_print: bool
- :return: set[set]
+ :rtype: MathSet | None
"""
- valid_results = list()
for a in results:
- # TODO is this fastest?
if result.value == a.value:
- valid_results.append(a)
- print("Calculated result: " + format_way(a, const_sets, results) + " --> " + str(a)) if do_print else None
- return valid_results
+ if do_print:
+ print("Calculated result: " + format_way(a.way, reversed_const_dict, results) + " --> " + str(a))
+ return a
+ return None
-def search(const_sets, result, not_allowed=None, identity=None, do_print=True):
+def search(const_dict, result, not_allowed=None, identity=None, overflow=30, range_int=20, do_print=True):
"""
- :type const_sets: dict[str, set[frozenset | int | tuple] | MathSet]
- :type result: set[frozenset | int | tuple] | MathSet
- :type not_allowed: list
- :type identity: Identity
+ Search for way to get from consts by 'const_dict' to result
+ :type const_dict: dict[str, set[frozenset | int | tuple] | MathSet] | ConstDictType
+ :type result: set[frozenset | int | tuple] | MathSet | ResultType
+ :type not_allowed: list[MODE]
+ :type identity: RelationMathSet | None
+ :type overflow: int
+ :type range_int: int
:type do_print: bool
- :rtype: list[MathSet] | None
+ :rtype: ResultWay | None
+ :raises ValueError:
"""
-
if not_allowed is None:
- not_allowed = [4, 5, 8, 9, 10, 11, 12, 13]
-
- # UPDATE const_sets with frozen-sets to const_sets with MathSets
- for y in const_sets.keys():
- if type(const_sets[y]) == set:
- const_sets[y] = MathSet(SetSolver1.helper.update.to_tiny_math_set(const_sets[y]), identity, STATUS.CONST)
- # UPDATE result with frozen-sets to result with MathSets
- result = MathSet(SetSolver1.helper.update.to_tiny_math_set(result), identity, STATUS.CONST)
-
- if list(const_sets.values()) == set(list(const_sets.values())):
+ not_allowed = SetSolver1.MODE.DEFAULT_NOT_ALLOWED
+
+ # UPDATE const_dict with frozen-sets to const_dict with MathSets
+ for y in const_dict.keys():
+ if type(const_dict[y]) == set:
+ if sum(1 for x in const_dict[y] if type(x) != tuple) == 0:
+ const_dict[y] = RelationMathSet(const_dict[y], identity, CONST_WAY)
+ else:
+ const_dict[y] = SimpleMathSet(SetSolver1.helper.update.to_tiny_math_set(const_dict[y]), CONST_WAY)
+ const_dict[y].correct_way()
+
+ const_dict: dict[str, MathSet] | ConstDictType
+ consts = list(const_dict.values())
+ if consts == set(consts):
raise ValueError('the dictionary values of set constants must be unique')
+ reversed_const_dict = dict((v, k) for k, v in const_dict.items())
+ sorted_results = sorted_consts = sorted(consts, key=lambda i: i.sort_key())
- results: set[MathSet] = set(const_sets.values())
-
- len_results_old = None
- for len_obj in range(range_int):
- len_results = len(results)
- print(str(round((len_obj/(range_int-1))*100)) + "% / " + str(len_results)) if do_print else None
- if len_results == len_results_old:
- break # performance optimization
- len_results_old = len_results
- # TODO is sorted results.copy() better?
- for x in results.copy():
- for y in [x for x in range(14) if x not in not_allowed]:
- for z in const_sets.values():
- new = tools(y, x, z)
- check_set(new, const_sets, results)
- valid_results = get_valid_results(const_sets, result, results, do_print)
- if len(valid_results) > 0:
- return valid_results
-
- len_results_old = None
- for len_obj in range(range_int):
- len_results = len(results)
- print("all: " + str(round((len_obj/(range_int-1))*100)) + "% / " + str(len_results)) if do_print else None
- if len_results == len_results_old:
- break # performance optimization
- len_results_old = len_results
- temp_results_list_for_power_set = results.copy()
- # for x, y in combinations_with_replacement(results, 2):
- for x, y in combinations_with_replacement(sorted(results, key=lambda i: i.sort_key()), 2):
- for c in [x for x in range(14) if x not in not_allowed + [6, 7]]:
- new = tools(c, x, y)
- check_set(new, const_sets, results)
- if 6 not in not_allowed:
- # TODO is sorted temp_results_list_for_power_set better?
- for x in temp_results_list_for_power_set:
- new = MathSet(frozenset(), x.identity, (6, x, None)) if x.total_deep_len() >= (overflow / 2) \
- else x.power_set((6, x, None))
- # TODO None could be here a MathSet with value = None
- check_set(new, const_sets, results)
- valid_results = get_valid_results(const_sets, result, results, do_print)
- if len(valid_results) > 0:
- return valid_results
+ # UPDATE result with frozen-sets to result with MathSets
+ if type(result) == set:
+ result = SimpleMathSet(SetSolver1.helper.update.to_tiny_math_set(result), RESULT)
+ if isinstance(result, ResultType):
+ result = result.get()
+ result: MathSet
+
+ very_cool = [1 if x.is_multi_mode() else 0 for x in SetSolver1.MODE.SORTED_CHOOSE_BY_INDEX if x not in not_allowed]
+
+ results: set[MathSet] = set(consts)
+
+ for mode in (1, 2):
+ len_results_old = None
+ for len_obj in range(range_int):
+ len_results = len(results)
+ print(str(mode) + ": " + str(round((len_obj/(range_int-1))*100)) + "% / " + str(len_results))\
+ if do_print else None
+ if len_results == len_results_old:
+ break # performance optimization
+ len_results_old = len_results
+ if mode == 1:
+ my_iter = product(
+ sorted_results,
+ chain(
+ *(
+ product(
+ sorted_consts if x.is_multi_mode() else [False],
+ [x]
+ ) for x in SetSolver1.MODE.SORTED_CHOOSE_BY_INDEX if x not in not_allowed)
+ )
+ )
+ iter_list = list()
+ for x, (y, c) in my_iter:
+ iter_list.append((x, y, c))
+ else:
+ my_iter = compress(
+ product(
+ combinations_with_replacement(sorted_results, 2),
+ [x for x in SetSolver1.MODE.SORTED_CHOOSE_BY_INDEX if x not in not_allowed]
+ ), [
+ 1 if x or y == len(sorted_results)-z-1 else 0
+ for z in range(len(sorted_results))
+ for y in range(len(sorted_results)-z)
+ for x in very_cool
+ ]
+ )
+ iter_list = list()
+ for (x, y), c in my_iter:
+ iter_list.append((x, y, c))
+
+ for x, y, c in iter_list:
+ new = tools(c, x, y, overflow)
+ results.add(new) if new is not None and new.total_deep_len() <= overflow else None
+ if c[2] == 0:
+ new = tools(c, y, x, overflow)
+ results.add(new) if new is not None and new.total_deep_len() <= overflow else None
+ valid_result = found_result(reversed_const_dict, result, results, do_print)
+ if valid_result is not None:
+ return ResultWay(valid_result, const_dict, reversed_const_dict, results)
+ sorted_results = sorted(results, key=lambda i: i.sort_key())
print("Nothing found :(") if do_print else None
return None
-
-
-overflow = 30
-range_int = 20
-DEBUG = False
diff --git a/SetSolver1/math_set.py b/SetSolver1/math_set.py
deleted file mode 100644
index aec115b..0000000
--- a/SetSolver1/math_set.py
+++ /dev/null
@@ -1,365 +0,0 @@
-from __future__ import annotations
-from itertools import chain, combinations
-import SetSolver1.MODE
-from SetSolver1.STATUS import STATUS
-
-
-class Identity:
- value: frozenset[int]
-
- def __init__(self, value):
- if type(value) == frozenset:
- self.value = value
- elif type(value) == set or type(value) == list:
- self.value = frozenset(value)
- else:
- raise ValueError("value not found")
-
- self.math_set = MathSet(self.value, self, STATUS.NONE)
-
- def __repr__(self):
- return "{0}({1})".format(type(self).__name__, set(self.value))
-
- def __hash__(self):
- return hash(self.value)
-
-
-class TinyMathSet(frozenset):
- _total_deep_len = None
-
- def __repr__(self):
- if self == frozenset():
- return "{}"
- return str(set(self))
-
- def deep_len(self):
- return sum(el.deep_len() if isinstance(el, TinyMathSet) else 1 for el in self)
-
- def total_deep_len(self):
- if self._total_deep_len is None:
- self._total_deep_len = sum(el.total_deep_len()+1 if isinstance(el, TinyMathSet) else 1 for el in self)
- return self._total_deep_len
-
-
-class MathSet:
- value: frozenset[TinyMathSet | int | tuple]
- identity: Identity | None
- way: (int, MathSet | None, MathSet | None) | STATUS
-
- def __init__(self, value, identity, way):
- """
- init MathSet
- :type value: frozenset | collections.abc.Iterable
- :type identity: Identity | None
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- """
- if type(value) == frozenset:
- self.value = value
- else:
- self.value = frozenset(value)
-
- self.identity = identity
- if way is None:
- way = STATUS.NONE
- self.way = way
-
- def __str__(self):
- if self.is_empty():
- return "{}"
- return str(set(self.value))
-
- def __repr__(self):
- return self.value, self.identity, self.way
-
- def __hash__(self):
- # Default: hash(x)==id(x)/16
- # https://stackoverflow.com/a/11324771
- # https://docs.python.org/3/glossary.html#term-hashable
- return hash(self.value)
-
- def __eq__(self, other):
- if isinstance(other, MathSet):
- return self.value == other.value
- print("NotImplemented Equality Compare")
- return NotImplemented
-
- def __len__(self):
- """
- :rtype: int
- """
- return len(self.value)
-
- def type_check(self, y):
- """
- Check if the type of MathSets is comparable
- :type y: MathSet
- """
- if self.identity != y.identity:
- raise TypeError("type_check error")
-
- def deep_len(self):
- return sum(el.deep_len() if isinstance(el, TinyMathSet) else 1 for el in self.value)
-
- def total_deep_len(self):
- return sum(el.total_deep_len()+1 if isinstance(el, TinyMathSet) else 1 for el in self.value)
-
- def walk_way(self, going_by=None):
- if self.way == STATUS.NONE:
- raise ValueError("STATUS.NONE not allowed here")
- if self.way == STATUS.CONST:
- return 0
-
- mode = SetSolver1.MODE.CHOOSE_BY_INDEX[self.way[0]]
- if going_by is None:
- going_by = mode[2]
- # set to priority of operator
- # to sort equal length like (pow(pow((A-A)))+B) / (pow((pow(A)&B))+B) [Aufgabe 2]
- lt = list()
- for i in mode[1]:
- if self.way[i] is not None:
- lt.append(self.way[i].walk_way())
- return sum(lt) + going_by
-
- def sort_key(self):
- return self.walk_way(going_by=1), self.walk_way()
-
- def is_empty(self):
- """
- Is MathSet empty?
- :rtype: bool
- """
- return self.value == frozenset()
-
- def union(self, y, way=None):
- """
- German: Vereinigungsmenge
- :type y: MathSet
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- self.type_check(y)
- # self.value.union(y.value)
- copy = set(self.value)
- copy.update(y.value)
- return MathSet(copy, self.identity, way)
-
- def complement(self, y, way=None):
- """
- German: Komplement - Subtraktion von Mengen
- :type y: MathSet
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- self.type_check(y)
- return MathSet(self.value.difference(y.value), self.identity, way)
-
- def intersection(self, y, way=None):
- """
- German: Schnittmenge
- :type y: MathSet
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- self.type_check(y)
- return MathSet(self.value.intersection(y.value), self.identity, way)
-
- def power_set(self, way=None):
- """
- German: Potenzmenge
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- return MathSet(
- [TinyMathSet(y) for y in chain.from_iterable(
- combinations(self.value, i) for i in range(len(self) + 1))],
- self.identity, way)
-
- def composition(self, y, way=None):
- """
- TODO optimization
- German: Verkettung
- :type y: MathSet
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- self.type_check(y)
- lst = list()
- for x1 in self.value:
- for y1 in y.value:
- if x1[1] == y1[0]:
- lst.append((x1[0], y1[1]))
- return MathSet(lst, self.identity, way)
-
- def symmetric_difference(self, y, way=None):
- """
- German: Symmetrische Differenz
- :type y: MathSet
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- self.type_check(y)
- return MathSet(self.value.symmetric_difference(y.value), self.identity, way)
-
- def do(self):
- """
- German: Erstelle Relation aus Menge
- :rtype: MathSet
- """
- items = list()
- for x1 in self.value:
- if type(x1) != int and type(x1) != str:
- return None
- else:
- for x2 in self.value:
- items.append((x1, x2))
- return MathSet(items, self.identity, STATUS.NONE)
-
- def converse_relation(self, way=None):
- """
- TODO optimization
- German: Inverse (Umkehrrelation)
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- return MathSet(((x1[1], x1[0]) for x1 in self.value), self.identity, way)
-
- def reflexive_closure(self, way=None):
- """
- TODO optimization
- German: Reflexive Hülle
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- return MathSet(list(self.value) + [(x3, x3) for x3 in set([x1[x2] for x2 in range(2) for x1 in self.value])],
- self.identity, way)
-
- def transitive_closure(self, way=None):
- """
- TODO optimization
- German: Transitive Hülle
- :type way: (int, MathSet | None, MathSet | None) | STATUS
- :rtype: MathSet
- """
- # {(1 , 1) , (2 , #3#) , (#3# , 1)} -> {(1 , 1) , #(2 , 1)# , (2 , 3), (3 , 1)}
- return MathSet(list(self.value) + [(x1[0], x2[1]) for x2 in self.value for x1 in self.value if x1[1] == x2[0]],
- self.identity, way)
-
- def is_reflexive(self):
- """
- :rtype: bool
- """
- if self.identity is None:
- return self.value == self.reflexive_closure().value
- return self.identity.math_set.is_subset(self)
-
- def is_irreflexive(self):
- """
- :rtype: bool
- """
- if self.identity is None:
- """
- One-Line
- return frozenset((x3, x3) for x3 in set([x1[x2] for x2 in range(2) for x1 in self.value])
- if (x3, x3) in self.value) == frozenset()
- """
- for x1 in self.value:
- if (x1[0], x1[0]) in self.value or (x1[1], x1[1]) in self.value:
- return False
- return True
- return self.intersection(self.identity.math_set).is_empty()
-
- def is_subset(self, y):
- """
- is_subset
- :type y: MathSet
- :rtype: MathSet
- """
- # self.value.issubset(y.value)
- self.type_check(y)
- for x1 in self.value:
- if x1 not in y.value:
- return False
- return True
-
- def is_symmetric_relation(self):
- """
- :rtype: bool
- """
- return self.converse_relation().is_subset(self)
-
- def is_asymmetric_relation(self):
- """
- :rtype: bool
- """
- return self.intersection(self.converse_relation()).is_empty()
-
- def is_antisymmetric_relation(self):
- """
- :rtype: bool
- """
- if self.identity is None:
- for x1 in self.value:
- if x1[::-1] in self.value and not x1[0] == x1[1]:
- return False
- return True
- return self.intersection(self.converse_relation()).is_subset(self.identity.math_set)
-
- def is_transitive(self):
- """
- :rtype: bool
- """
- return self.value == self.transitive_closure().value
-
- def is_preorder(self):
- """
- German: Quasiordnung
- :return: bool
- """
- return self.is_reflexive() and self.is_transitive()
-
- def is_equivalence_relation(self):
- """
- German: Äquivalenzrelation (symmetrische Quasiordnung)
- :return: bool
- """
- return self.is_preorder() and self.is_symmetric_relation()
-
- def is_non_strict_partial_order(self):
- """
- German: Halbordnung (partielle Ordnung)
- :return: bool
- """
- return self.is_reflexive() and self.is_antisymmetric_relation() and self.is_transitive()
-
- def is_strict_partial_order(self):
- """
- German: Strikte Ordnung
- :return: bool
- """
- return self.is_irreflexive() and self.is_transitive() and self.is_asymmetric_relation()
-
- def get_identity(self):
- """
- Menge auf die die binäre Relation beruht
- :rtype: Identity | None
- """
- items = list()
- for x in self.value:
- if type(x) != int and type(x) != str:
- return None
- else:
- items.append((x, x))
-
- return Identity(items)
-
- def print_properties(self):
- """
- Print all properties of this set with relations
- :return: None
- """
- print("is_reflexive: " + str(self.is_reflexive()))
- print("is_irreflexive: " + str(self.is_irreflexive()))
- print("is_symmetrisch: " + str(self.is_symmetric_relation()))
- print("is_asymmetrisch: " + str(self.is_asymmetric_relation()))
- print("is_antisymmetrisch: " + str(self.is_antisymmetric_relation()))
- print("is_transitiv: " + str(self.is_transitive()))
diff --git a/TODO.txt b/TODO.txt
deleted file mode 100644
index 8532d96..0000000
--- a/TODO.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# TODO max größe vom Ausdruck
-# TODO for search for frozenset({})
-
-# TODO create own class as subtype of set and use it for union, complement etc.
diff --git a/beispiele.md b/beispiele.md
index 0572fe0..3c9b961 100644
--- a/beispiele.md
+++ b/beispiele.md
@@ -1,23 +1,37 @@
# German Examples
+Credits for the examples goes to: https://gitlab.imn.htwk-leipzig.de/autotool/all0/
+
## Inhalt
### Mengen
-- [Aufgabe (demo)](#aufgabe-demo)
-- [Aufgabe 1](#aufgabe-1)
-- [Aufgabe 2](#aufgabe-2)
-- [Aufgabe 3](#aufgabe-3)
-- [Aufgabe 4](#aufgabe-4)
-- [Aufgabe 5](#aufgabe-5)
-- [Aufgabe 6](#aufgabe-6)
+- [Aufgabe 1.demo](#aufgabe-1.demo)
+- [Aufgabe 1.1](#aufgabe-1.1)
+- [Aufgabe 1.2](#aufgabe-1.2)
+- [Aufgabe 1.3](#aufgabe-1.3)
+- [Aufgabe 1.4](#aufgabe-1.4)
+- [Aufgabe 1.5](#aufgabe-1.5)
+- [Aufgabe 1.6](#aufgabe-1.6)
### Mengen mit Relationen
-- coming soon
+- [Aufgabe 2.demo](#aufgabe-2.demo)
+- [Aufgabe 2.1](#aufgabe-2.1)
+- [Aufgabe 2.2](#aufgabe-2.2)
+- [Aufgabe 2.3](#aufgabe-2.3)
+- [Aufgabe 2.4](#aufgabe-2.4)
+
+
+### MultiMengen
+- [Aufgabe 3.demo](#aufgabe-3.demo)
+- [Aufgabe 3.1](#aufgabe-3.1)
+- [Aufgabe 3.2](#aufgabe-3.2)
+
+---
---
-### [Aufgabe (demo)](/examples/sets/aufgabe0.py)
+### [Aufgabe 1.demo](/examples/sets/exercice0.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
@@ -37,14 +51,14 @@ und diese vordefinierten Konstanten:
A = {1, 2}
B = {1}
-Calculated result(s):
+Calculated result:
(pow(A)-pow(B)) --> {{2}, {1, 2}}
- Calculation ended after 0.56 sec
+ Calculation ended after 0.063 sec
* * *
-### [Aufgabe 1](/examples/sets/aufgabe1.py)
+### [Aufgabe 1.1](/examples/sets/exercice1.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
{{{{3}}}}
@@ -63,14 +77,14 @@ und diese vordefinierten Konstanten:
A = {{}, {2}, {3}}
B = {{}, {{3}}}
-Calculated result(s):
+Calculated result:
(pow((B-A))-A) --> {{{{3}}}}
- Calculation ended after 0.005 sec
+ Calculation ended after 0.001 sec
* * *
-### [Aufgabe 2](/examples/sets/aufgabe2.py)
+### [Aufgabe 1.2](/examples/sets/exercice2.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
{{}, {3}, {5}, {{}}}
@@ -89,14 +103,14 @@ und diese vordefinierten Konstanten:
A = {{2, {}}, {5}}
B = {{}, {3}, {5}}
-Calculated result(s):
+Calculated result:
(pow(pow((A-A)))+B) --> {{3}, {{}}, {}, {5}}
- Calculation ended after 0.013 sec
+ Calculation ended after 0.003 sec
* * *
-### [Aufgabe 3](/examples/sets/aufgabe3.py)
+### [Aufgabe 1.3](/examples/sets/exercice3.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
{6, {2}}
@@ -116,14 +130,14 @@ und diese vordefinierten Konstanten:
V = {1, 2, 4, 6, {3}}
W = {4, {2}}
-Calculated result(s):
+Calculated result:
- (((W-V)+U)-(U-V)) --> {{2}, 6}
- Calculation ended after 320.397 sec
+ ((V+W)-(V-U)) --> {{2}, 6}
+ Calculation ended after 4.58 sec
* * *
-### [Aufgabe 4](/examples/sets/aufgabe4.py)
+### [Aufgabe 1.4](/examples/sets/exercice4.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
{{}, {1, 2, {3}}, {1, {3}}, {2, {3}}, {{3}}}
@@ -142,14 +156,14 @@ und diese vordefinierten Konstanten:
A = {1, 2}
B = {{3}}
-Calculated result(s):
+Calculated result:
(pow(B)+(pow((A+B))-pow(A))) --> {{{3}, 1}, {{3}, 1, 2}, {}, {{3}, 2}, {{3}}}
- Calculation ended after 2.889 sec
+ Calculation ended after 0.29 sec
* * *
-### [Aufgabe 5](/examples/sets/aufgabe5.py)
+### [Aufgabe 1.5](/examples/sets/exercice5.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
@@ -169,14 +183,14 @@ und diese vordefinierten Konstanten:
A = {{2, {5, {1}}}}
B = {{}, {5, {}}}
-Calculated result(s):
+Calculated result:
(pow((B-pow(A)))+B) --> {{}, {{}, 5}, {{{}, 5}}}
- Calculation ended after 0.008 sec
+ Calculation ended after 0.002 sec
* * *
-### [Aufgabe 6](/examples/sets/aufgabe6.py)
+### [Aufgabe 1.6](/examples/sets/exercice6.py)
Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
@@ -196,7 +210,252 @@ und diese vordefinierten Konstanten:
A = {4, {4}, {5}}
B = {5, {}, {{}}}
-Calculated result(s):
+Calculated result:
((A+B)&pow(B)) --> {{}, {{}}, {5}}
- Calculation ended after 32.459 sec
+ Calculation ended after 0.994 sec
+
+---
+---
+
+### [Aufgabe 2.demo](/examples/sets-relations/exercice0.py)
+
+Die folgende Aufgabe bezieht sich auf Relationen
+über dem Grundbereich mkSet
+
+ [ 1, 2, 3]
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {(3 , 3)}
+
+Der Ausdruck soll höchstens die Größe _7_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &, .]
+ einstellige : [ inverse, reflexive_cl, transitive_cl]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ R = {(1 , 2) , (3 , 2)}
+ S = {(1 , 1) , (2 , 3) , (3 , 1)}
+
+Calculated result:
+
+ ((inverse(S)&R).S) --> {(3, 3)}
+ Calculation ended after 0.004 sec
+
+* * *
+
+### [Aufgabe 2.1](/examples/sets-relations/exercice1.py)
+
+Die folgende Aufgabe bezieht sich auf Relationen
+über dem Grundbereich mkSet
+
+ [ 1, 2, 3]
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {(1 , 1) , (1 , 2) , (1 , 3), (2 , 1) , (2 , 2)}
+
+Der Ausdruck soll höchstens die Größe _20_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &, .]
+ einstellige : [ ]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ R = {(2 , 1) , (3 , 1) , (3 , 2)}
+ S = {(1 , 2) , (1 , 3) , (2 , 1)}
+
+Calculated result:
+
+ (S.((S.(S+R))+R)) --> {(1, 2), (2, 1), (2, 2), (1, 1), (1, 3)}
+ Calculation ended after 0.007 sec
+
+* * *
+
+### [Aufgabe 2.2](/examples/sets-relations/exercice2.py)
+
+Die folgende Aufgabe bezieht sich auf Relationen
+über dem Grundbereich mkSet
+
+ [ 1, 2, 3, 4]
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {(1 , 3) , (3 , 1) , (3 , 2) , (3 , 4) , (4 , 3)}
+
+Der Ausdruck soll höchstens die Größe _30_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &, .]
+ einstellige : [ inverse]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ R = {(1 , 1) , (1 , 4) , (3 , 3) , (4 , 4)}
+ S = {(2 , 3) , (3 , 1) , (3 , 2) , (3 , 4)}
+
+Calculated result:
+
+ (R.(inverse(S)+S)) --> {(3, 4), (4, 3), (3, 1), (3, 2), (1, 3)}
+ Calculation ended after 0.003 sec
+
+* * *
+
+### [Aufgabe 2.3](/examples/sets-relations/exercice3.py)
+
+Die folgende Aufgabe bezieht sich auf Relationen
+über dem Grundbereich mkSet
+
+ [ 1, 2, 3, 4]
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {(3 , 2) , (3 , 3) , (4 , 1) , (4 , 3) , (4 , 4)}
+
+Der Ausdruck soll höchstens die Größe _20_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &, .]
+ einstellige : [ inverse, transitive_cl, reflexive_cl]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ R = {(1 , 3) , (2 , 1) , (3 , 1) , (4 , 3)}
+ S = {(3 , 2) , (3 , 3) , (4 , 3) , (4 , 4)}
+
+Calculated result:
+
+ (((S&R).R)+S) --> {(4, 4), (3, 3), (4, 3), (3, 2), (4, 1)}
+ Calculation ended after 0.009 sec
+
+* * *
+
+### [Aufgabe 2.4](/examples/sets-relations/exercice4.py)
+
+Die folgende Aufgabe bezieht sich auf Relationen
+über dem Grundbereich mkSet
+
+ [ 1, 2, 3, 4]
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {(3 , 1)}
+
+Der Ausdruck soll höchstens die Größe _50_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &, .]
+ einstellige : [ inverse, transitive_cl, reflexive_cl]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ R = {(1 , 2) , (4 , 3)}
+ S = {(1 , 3) , (2 , 4)}
+
+Calculated result:
+
+ inverse(((R.S).R)) --> {(3, 1)}
+ Calculation ended after 0.003 sec
+
+---
+---
+
+### [Aufgabe 3.demo](/examples/multisets/exercice0.py)
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {q:1}
+
+Der Ausdruck soll höchstens die Größe _30_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &]
+ einstellige : [ ]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ A = {p:1, q:3}
+ B = {q:2, r:3}
+ C = {q:1, r:1}
+
+Calculated result:
+
+ (C&A) --> {'q': 1}
+ Calculation ended after 0.0 sec
+
+* * *
+
+### [Aufgabe 3.1](/examples/multisets/exercice1.py)
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {p:3, q:7, s:5}
+
+Der Ausdruck soll höchstens die Größe _25_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &]
+ einstellige : [ ]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ A = {p:2, q:1, r:2, t:2, u:4}
+ B = {p:1, q:5, s:5}
+
+Calculated result:
+
+ ((A&B)+((A&B)+B)) --> {'p': 3, 'q': 7, 's': 5}
+ Calculation ended after 0.305 sec
+
+* * *
+
+### [Aufgabe 3.2](/examples/multisets/exercice2.py)
+
+Gesucht ist ein Ausdruck (Term) mit dieser Bedeutung:
+
+ {p:4, r:11, t:5, u:8}
+
+Der Ausdruck soll höchstens die Größe _30_ haben.\
+Sie dürfen diese Symbole benutzen
+
+ Operator-Symbole:
+ zweistellige : [ +, -, &]
+ einstellige : [ ]
+ nullstellige : [ ]
+ Funktions-Symbole: [ ]
+
+und diese vordefinierten Konstanten:
+
+ A = {p:2, r:5, t:3, u:2}
+ B = {q:5, s:2, t:1}
+ C = {r:1, u:4}
+
+Calculated result:
+
+ (((A+C)+A)-B) --> {'p': 4, 'r': 11, 't': 5, 'u': 8}
+ Calculation ended after 0.004 sec
diff --git a/examples/multisets/exercice0.py b/examples/multisets/exercice0.py
new file mode 100644
index 0000000..5a961fd
--- /dev/null
+++ b/examples/multisets/exercice0.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, MultiMathSetConstDictType, MultiMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = MultiMathSetConstDictType(
+ {
+ "A": {"p": 1, "q": 3},
+ "B": {"q": 2, "r": 3},
+ "C": {"q": 1, "r": 1}
+ }
+)
+
+# Here you set your wanted solution.
+result = MultiMathSetResultType({"q": 1})
+
+not_allowed = [MODE.UNION, MODE.COMPLEMENT, MODE.COMPOSITION, MODE.POWER_SET, MODE.CONVERSE_RELATION,
+ MODE.REFLEXIVE_CLOSURE, MODE.TRANSITIVE_CLOSURE]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/multisets/exercice1.py b/examples/multisets/exercice1.py
new file mode 100644
index 0000000..305fb14
--- /dev/null
+++ b/examples/multisets/exercice1.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, MultiMathSetConstDictType, MultiMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = MultiMathSetConstDictType(
+ {
+ "A": {"p": 2, "q": 1, "r": 2, "t": 2, "u": 4},
+ "B": {"p": 1, "q": 5, "s": 5}
+ }
+)
+
+# Here you set your wanted solution.
+result = MultiMathSetResultType({"p": 3, "q": 7, "s": 5})
+
+not_allowed = [MODE.UNION, MODE.COMPLEMENT, MODE.COMPOSITION, MODE.POWER_SET, MODE.CONVERSE_RELATION,
+ MODE.REFLEXIVE_CLOSURE, MODE.TRANSITIVE_CLOSURE]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/multisets/exercice2.py b/examples/multisets/exercice2.py
new file mode 100644
index 0000000..c38c3a0
--- /dev/null
+++ b/examples/multisets/exercice2.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, MultiMathSetConstDictType, MultiMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = MultiMathSetConstDictType(
+ {
+ "A": {"p": 2, "r": 5, "t": 3, "u": 2},
+ "B": {"q": 5, "s": 2, "t": 1},
+ "C": {"r": 1, "u": 4}
+ }
+)
+
+# Here you set your wanted solution.
+result = MultiMathSetResultType({"p": 4, "r": 11, "t": 5, "u": 8})
+
+not_allowed = [MODE.UNION, MODE.COMPLEMENT, MODE.COMPOSITION, MODE.POWER_SET, MODE.CONVERSE_RELATION,
+ MODE.REFLEXIVE_CLOSURE, MODE.TRANSITIVE_CLOSURE]
+
+start_time = timer()
+search(const_dict, result, not_allowed, overflow=33)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/aufgabe1.py b/examples/sets-relations/aufgabe1.py
deleted file mode 100644
index ff494e7..0000000
--- a/examples/sets-relations/aufgabe1.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int | tuple]] = {
- "R": {(2, 1), (3, 1), (3, 2)},
- "S": {(1, 2), (1, 3), (2, 1)}
-}
-
-# Here you set your wanted solution.
-result = {(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)}
-
-not_allowed = [6, 7, 8, 9, 10, 11, 12, 13]
-
-start_time = timer()
-search(const_sets, result, not_allowed)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/aufgabe4.py b/examples/sets-relations/aufgabe4.py
deleted file mode 100644
index 65bfcf8..0000000
--- a/examples/sets-relations/aufgabe4.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int | tuple]] = {
- "R": {(1, 2), (4, 3)},
- "S": {(1, 3), (2, 4)}
-}
-
-# Here you set your wanted solution.
-result = {(3, 1)}
-
-not_allowed = [6, 7]
-
-start_time = timer()
-search(const_sets, result, not_allowed)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/exercice0.py b/examples/sets-relations/exercice0.py
new file mode 100644
index 0000000..482e5e2
--- /dev/null
+++ b/examples/sets-relations/exercice0.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, RelationMathSetConstDictType, RelationMathSetResultType,\
+ RelationMathSetIdentityType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you can set an identity relation.
+identity = RelationMathSetIdentityType({(1, 1), (2, 2), (3, 3)}).get()
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = RelationMathSetConstDictType(
+ {
+ "R": {(1, 2), (3, 2)},
+ "S": {(1, 1), (2, 3), (3, 1)}
+ },
+ identity=identity
+)
+
+# Here you set your wanted solution.
+result = RelationMathSetResultType({(3, 3)}, identity=identity)
+
+not_allowed = [MODE.POWER_SET, MODE.MULTISET_DIFFERENCE, MODE.MULTISET_DISJOINT_UNION]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/exercice1.py b/examples/sets-relations/exercice1.py
new file mode 100644
index 0000000..28d9366
--- /dev/null
+++ b/examples/sets-relations/exercice1.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, RelationMathSetConstDictType, RelationMathSetResultType, \
+ RelationMathSetIdentityType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you can set an identity relation.
+identity = RelationMathSetIdentityType({(1, 1), (2, 2), (3, 3)}).get()
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = RelationMathSetConstDictType(
+ {
+ "R": {(2, 1), (3, 1), (3, 2)},
+ "S": {(1, 2), (1, 3), (2, 1)}
+ },
+ identity=identity
+)
+
+# Here you set your wanted solution.
+result = RelationMathSetResultType({(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)}, identity=identity)
+
+not_allowed = [MODE.POWER_SET, MODE.CONVERSE_RELATION, MODE.REFLEXIVE_CLOSURE, MODE.TRANSITIVE_CLOSURE,
+ MODE.MULTISET_DIFFERENCE, MODE.MULTISET_DISJOINT_UNION]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/exercice2.py b/examples/sets-relations/exercice2.py
new file mode 100644
index 0000000..8bb7ab3
--- /dev/null
+++ b/examples/sets-relations/exercice2.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, RelationMathSetConstDictType, RelationMathSetResultType, \
+ RelationMathSetIdentityType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you can set an identity relation.
+identity = RelationMathSetIdentityType({(1, 1), (2, 2), (3, 3)}).get()
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = RelationMathSetConstDictType(
+ {
+ "R": {(1, 1), (1, 4), (3, 3), (4, 4)},
+ "S": {(2, 3), (3, 1), (3, 2), (3, 4)}
+ },
+ identity=identity
+)
+
+# Here you set your wanted solution.
+result = RelationMathSetResultType({(1, 3), (3, 1), (3, 2), (3, 4), (4, 3)}, identity=identity)
+
+not_allowed = [MODE.POWER_SET, MODE.REFLEXIVE_CLOSURE, MODE.TRANSITIVE_CLOSURE,
+ MODE.MULTISET_DIFFERENCE, MODE.MULTISET_DISJOINT_UNION]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/exercice3.py b/examples/sets-relations/exercice3.py
new file mode 100644
index 0000000..bd94119
--- /dev/null
+++ b/examples/sets-relations/exercice3.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, RelationMathSetConstDictType, RelationMathSetResultType, \
+ RelationMathSetIdentityType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you can set an identity relation.
+identity = RelationMathSetIdentityType({(1, 1), (2, 2), (3, 3)}).get()
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = RelationMathSetConstDictType(
+ {
+ "R": {(1, 3), (2, 1), (3, 1), (4, 3)},
+ "S": {(3, 2), (3, 3), (4, 3), (4, 4)}
+ },
+ identity=identity
+)
+
+# Here you set your wanted solution.
+result = RelationMathSetResultType({(3, 2), (3, 3), (4, 1), (4, 3), (4, 4)}, identity=identity)
+
+not_allowed = [MODE.POWER_SET, MODE.MULTISET_DIFFERENCE, MODE.MULTISET_DISJOINT_UNION]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/exercice4.py b/examples/sets-relations/exercice4.py
new file mode 100644
index 0000000..22a8619
--- /dev/null
+++ b/examples/sets-relations/exercice4.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, MODE, RelationMathSetConstDictType, RelationMathSetResultType, \
+ RelationMathSetIdentityType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you can set an identity relation.
+identity = RelationMathSetIdentityType({(1, 1), (2, 2), (3, 3)}).get()
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = RelationMathSetConstDictType(
+ {
+ "R": {(1, 2), (4, 3)},
+ "S": {(1, 3), (2, 4)}
+ },
+ identity=identity
+)
+
+# Here you set your wanted solution.
+result = RelationMathSetResultType({(3, 1)}, identity=identity)
+
+not_allowed = [MODE.POWER_SET, MODE.MULTISET_DIFFERENCE, MODE.MULTISET_DISJOINT_UNION]
+
+start_time = timer()
+search(const_dict, result, not_allowed)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe0.py b/examples/sets/aufgabe0.py
deleted file mode 100644
index 53ba667..0000000
--- a/examples/sets/aufgabe0.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {1, 2},
- "B": {1}
-}
-
-# Here you set your wanted solution.
-result = {frozenset({1, 2}), frozenset({2})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe1.py b/examples/sets/aufgabe1.py
deleted file mode 100644
index a53639f..0000000
--- a/examples/sets/aufgabe1.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {frozenset(), frozenset({2}), frozenset({3})},
- "B": {frozenset(), frozenset({frozenset({3})})}
-}
-
-# Here you set your wanted solution.
-result = {frozenset({frozenset({frozenset({3})})})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe2.py b/examples/sets/aufgabe2.py
deleted file mode 100644
index 70fc58e..0000000
--- a/examples/sets/aufgabe2.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {frozenset({2, frozenset()}), frozenset({5})},
- "B": {frozenset(), frozenset({3}), frozenset({5})}
-}
-
-# Here you set your wanted solution.
-result = {frozenset(), frozenset({3}), frozenset({5}), frozenset({frozenset()})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe3.py b/examples/sets/aufgabe3.py
deleted file mode 100644
index 6be1676..0000000
--- a/examples/sets/aufgabe3.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "U": {3, 5, 6, frozenset({1})},
- "V": {1, 2, 4, 6, frozenset({3})},
- "W": {4, frozenset({2})}
-}
-
-# Here you set your wanted solution.
-result = {6, frozenset({2})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe4.py b/examples/sets/aufgabe4.py
deleted file mode 100644
index ba0e7f5..0000000
--- a/examples/sets/aufgabe4.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {1, 2},
- "B": {frozenset({3})}
-}
-
-# Here you set your wanted solution.
-result = {frozenset(), frozenset({1, 2, frozenset({3})}), frozenset({1, frozenset({3})}),
- frozenset({2, frozenset({3})}), frozenset({frozenset({3})})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe5.py b/examples/sets/aufgabe5.py
deleted file mode 100644
index 745bb16..0000000
--- a/examples/sets/aufgabe5.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from SetSolver1 import search
-from timeit import default_timer as timer
-
-# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
-
-# Here you set your predefined constants.
-# Please make sure that you do not assign a variable letter twice.
-# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {frozenset({2, frozenset({5, frozenset({1})})})},
- "B": {frozenset(), frozenset({5, frozenset()})}
-}
-
-# Here you set your wanted solution.
-result = {frozenset(), frozenset(frozenset({5, frozenset({})})), frozenset({frozenset(frozenset({5, frozenset({})}))})}
-
-
-start_time = timer()
-search(const_sets, result)
-print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/aufgabe6.py b/examples/sets/exercice0.py
similarity index 60%
rename from examples/sets/aufgabe6.py
rename to examples/sets/exercice0.py
index 140695c..e9caf49 100644
--- a/examples/sets/aufgabe6.py
+++ b/examples/sets/exercice0.py
@@ -1,4 +1,7 @@
-from SetSolver1 import search
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
from timeit import default_timer as timer
# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
@@ -6,15 +9,17 @@
# Here you set your predefined constants.
# Please make sure that you do not assign a variable letter twice.
# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int]] = {
- "A": {4, frozenset({4}), frozenset({5})},
- "B": {5, frozenset(), frozenset({frozenset()})}
-}
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {1, 2},
+ "B": {1}
+ }
+)
# Here you set your wanted solution.
-result = {frozenset(), frozenset({5}), frozenset({frozenset()})}
+result = SimpleMathSetResultType({frozenset({1, 2}), frozenset({2})})
start_time = timer()
-search(const_sets, result)
+search(const_dict, result)
print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/exercice1.py b/examples/sets/exercice1.py
new file mode 100644
index 0000000..55c2f12
--- /dev/null
+++ b/examples/sets/exercice1.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {frozenset(), frozenset({2}), frozenset({3})}, # string "[[],[2],[3]]" is allowed too
+ "B": {frozenset(), frozenset({frozenset({3})})} # string "{{},{{3}}}" too
+ }
+)
+
+# Here you set your wanted solution.
+result = SimpleMathSetResultType({frozenset({frozenset({frozenset({3})})})}) # as string "{{{{3}}}}"
+
+
+start_time = timer()
+search(const_dict, result)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/aufgabe0.py b/examples/sets/exercice2.py
similarity index 52%
rename from examples/sets-relations/aufgabe0.py
rename to examples/sets/exercice2.py
index 433c2b0..f5291e5 100644
--- a/examples/sets-relations/aufgabe0.py
+++ b/examples/sets/exercice2.py
@@ -1,4 +1,7 @@
-from SetSolver1 import search
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
from timeit import default_timer as timer
# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
@@ -6,16 +9,17 @@
# Here you set your predefined constants.
# Please make sure that you do not assign a variable letter twice.
# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int | tuple]] = {
- "R": {(1, 2), (3, 2)},
- "S": {(1, 1), (2, 3), (3, 1)}
-}
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {frozenset({2, frozenset()}), frozenset({5})},
+ "B": {frozenset(), frozenset({3}), frozenset({5})}
+ }
+)
# Here you set your wanted solution.
-result = {(3, 3)}
+result = SimpleMathSetResultType({frozenset(), frozenset({3}), frozenset({5}), frozenset({frozenset()})})
-not_allowed = [6, 7]
start_time = timer()
-search(const_sets, result, not_allowed)
+search(const_dict, result)
print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/aufgabe2.py b/examples/sets/exercice3.py
similarity index 56%
rename from examples/sets-relations/aufgabe2.py
rename to examples/sets/exercice3.py
index b8d0f14..ba4db4c 100644
--- a/examples/sets-relations/aufgabe2.py
+++ b/examples/sets/exercice3.py
@@ -1,4 +1,7 @@
-from SetSolver1 import search
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
from timeit import default_timer as timer
# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
@@ -6,16 +9,18 @@
# Here you set your predefined constants.
# Please make sure that you do not assign a variable letter twice.
# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int | tuple]] = {
- "R": {(1, 1), (1, 4), (3, 3), (4, 4)},
- "S": {(2, 3), (3, 1), (3, 2), (3, 4)}
-}
+const_dict = SimpleMathSetConstDictType(
+ {
+ "U": {3, 5, 6, frozenset({1})},
+ "V": {1, 2, 4, 6, frozenset({3})},
+ "W": {4, frozenset({2})}
+ }
+)
# Here you set your wanted solution.
-result = {(1, 3), (3, 1), (3, 2), (3, 4), (4, 3)}
+result = SimpleMathSetResultType({6, frozenset({2})})
-not_allowed = [6, 7, 10, 11, 12, 13]
start_time = timer()
-search(const_sets, result, not_allowed)
+search(const_dict, result)
print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/exercice4.py b/examples/sets/exercice4.py
new file mode 100644
index 0000000..0ed6f7b
--- /dev/null
+++ b/examples/sets/exercice4.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {1, 2},
+ "B": {frozenset({3})}
+ }
+)
+
+# Here you set your wanted solution.
+result = SimpleMathSetResultType(
+ {frozenset(), frozenset({1, 2, frozenset({3})}), frozenset({1, frozenset({3})}),
+ frozenset({2, frozenset({3})}), frozenset({frozenset({3})})}
+)
+
+
+start_time = timer()
+search(const_dict, result)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets/exercice5.py b/examples/sets/exercice5.py
new file mode 100644
index 0000000..3e9a647
--- /dev/null
+++ b/examples/sets/exercice5.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
+from timeit import default_timer as timer
+
+# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
+
+# Here you set your predefined constants.
+# Please make sure that you do not assign a variable letter twice.
+# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {frozenset({2, frozenset({5, frozenset({1})})})},
+ "B": {frozenset(), frozenset({5, frozenset()})}
+ }
+)
+
+# Here you set your wanted solution.
+result = SimpleMathSetResultType(
+ {frozenset(), frozenset(frozenset({5, frozenset({})})), frozenset({frozenset(frozenset({5, frozenset({})}))})}
+)
+
+
+start_time = timer()
+search(const_dict, result)
+print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/examples/sets-relations/aufgabe3.py b/examples/sets/exercice6.py
similarity index 54%
rename from examples/sets-relations/aufgabe3.py
rename to examples/sets/exercice6.py
index 0322d64..b78f8f4 100644
--- a/examples/sets-relations/aufgabe3.py
+++ b/examples/sets/exercice6.py
@@ -1,4 +1,7 @@
-from SetSolver1 import search
+#!/usr/bin/env python3
+# coding: utf-8
+
+from SetSolver1 import search, SimpleMathSetConstDictType, SimpleMathSetResultType
from timeit import default_timer as timer
# THIS IS AN EXAMPLE in /examples. See /beispiele.md for more information.
@@ -6,16 +9,17 @@
# Here you set your predefined constants.
# Please make sure that you do not assign a variable letter twice.
# Python dictionaries will otherwise only store the last value and overwrite the previous ones.
-const_sets: dict[str, set[frozenset | int | tuple]] = {
- "R": {(1, 3), (2, 1), (3, 1), (4, 3)},
- "S": {(3, 2), (3, 3), (4, 3), (4, 4)}
-}
+const_dict = SimpleMathSetConstDictType(
+ {
+ "A": {4, frozenset({4}), frozenset({5})},
+ "B": {5, frozenset(), frozenset({frozenset()})}
+ }
+)
# Here you set your wanted solution.
-result = {(3, 2), (3, 3), (4, 1), (4, 3), (4, 4)}
+result = SimpleMathSetResultType({frozenset(), frozenset({5}), frozenset({frozenset()})})
-not_allowed = [6, 7]
start_time = timer()
-search(const_sets, result, not_allowed)
+search(const_dict, result)
print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")
diff --git a/setup.py b/setup.py
index da79b10..0b3b6ec 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
setup(
name='SetSolver1',
- version='1!2021.11.2',
+ version='1!2021.12.2',
url='https://github.com/LukasWestholt/SetSolver1',
author='lukaswestholt',
author_email='support@lukaswestholt.de',
diff --git a/tests/one-liner_vs_fast.py b/tests/one-liner_vs_fast.py
index 6a35e97..3f03380 100644
--- a/tests/one-liner_vs_fast.py
+++ b/tests/one-liner_vs_fast.py
@@ -1,9 +1,10 @@
from timeit import default_timer as timer
-
# Is set irreflexive?
+
def a():
- return frozenset((x3, x3) for x3 in set([x1[x2] for x2 in range(2) for x1 in value]) if (x3, x3) in value) == frozenset()
+ return frozenset((x3, x3) for x3 in set([x1[x2] for x2 in range(2) for x1 in value]) if (x3, x3) in value) == \
+ frozenset()
def b():
diff --git a/tests/overall_speed.py b/tests/overall_speed.py
index 5a1453a..cd9f8b2 100644
--- a/tests/overall_speed.py
+++ b/tests/overall_speed.py
@@ -1,7 +1,7 @@
from SetSolver1 import search
from timeit import default_timer as timer
-const_sets: dict[str, set[frozenset | int]] = {
+const_dict: dict[str, set[frozenset | int]] = {
"A": {1, 2},
"B": {1}
}
@@ -12,5 +12,5 @@
start_time = timer()
for x in range(times):
- search(const_sets, result)
+ search(const_dict, result)
print("Calculation ended after " + str(round((timer() - start_time) * 1000) / 1000.0) + " sec")