From 4ad78cb3875c5653f8cb60f812c22a11256ecf8a Mon Sep 17 00:00:00 2001 From: Smoren Date: Thu, 26 Jan 2023 16:32:27 +0300 Subject: [PATCH 1/9] `Set::intersectPartial()` method added with smoke test. --- src/SetTheory/Set.php | 46 ++++ src/Util/Iter.php | 2 +- src/Util/JustifyMultipleIterator.php | 95 +++++++ src/Util/NoValueMonad.php | 29 +++ tests/SetTheory/SetOperationsTest.php | 354 ++++++++++++++++++++++++++ 5 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 src/Util/JustifyMultipleIterator.php create mode 100644 src/Util/NoValueMonad.php diff --git a/src/SetTheory/Set.php b/src/SetTheory/Set.php index fcb7720b4..5c11d85ae 100644 --- a/src/SetTheory/Set.php +++ b/src/SetTheory/Set.php @@ -2,6 +2,9 @@ namespace MathPHP\SetTheory; +use MathPHP\Util\JustifyMultipleIterator; +use MathPHP\Util\NoValueMonad; + /** * Set (Set Theory) * A set is a collection of distinct objects, considered as an object in @@ -428,6 +431,49 @@ public function intersect(Set ...$Bs): Set return new Set($intersection); } + /** + * TODO add + * + * @param int $m Min intersection count + * @param Set ...$Bs One or more sets + * + * @return Set + */ + public function intersectPartial(int $m, Set ...$Bs): Set + { + $B_members = []; + foreach ($Bs as $B) { + $B_members[] = $B->asArray(); + } + + $iterator = new JustifyMultipleIterator($this->asArray(), ...$B_members); + + $usageMap = []; + $intersection = []; + + foreach ($iterator as $values) { + foreach ($values as $value) { + if ($value instanceof NoValueMonad) { + continue; + } + + $key = $this->getKey($value); + + if (!isset($usageMap[$key])) { + $usageMap[$key] = 0; + } + + $usageMap[$key]++; + + if ($usageMap[$key] === $m) { + $intersection[] = $value; + } + } + } + + return new Set($intersection); + } + /** * Difference (relative complement) (A ∖ B) or (A - B) * Produces a new set with elements that are not in the other sets. diff --git a/src/Util/Iter.php b/src/Util/Iter.php index 1ccba22a9..2d1e1dee2 100644 --- a/src/Util/Iter.php +++ b/src/Util/Iter.php @@ -33,7 +33,7 @@ public static function zip(iterable ...$iterables): \MultipleIterator * * @return \Iterator|\IteratorIterator|\ArrayIterator */ - private static function makeIterator(iterable $iterable): \Iterator + public static function makeIterator(iterable $iterable): \Iterator { switch (true) { case $iterable instanceof \Iterator: diff --git a/src/Util/JustifyMultipleIterator.php b/src/Util/JustifyMultipleIterator.php new file mode 100644 index 000000000..013cde188 --- /dev/null +++ b/src/Util/JustifyMultipleIterator.php @@ -0,0 +1,95 @@ +> + * + * Based on IterTools PHP's IteratorFactory. + * @see https://github.com/markrogoyski/itertools-php + * @see https://github.com/markrogoyski/itertools-php/blob/main/src/Util/JustifyMultipleIterator.php + */ +class JustifyMultipleIterator implements \Iterator +{ + /** + * @var array<\Iterator> + */ + protected $iterators = []; + /** + * @var int + */ + protected $index = 0; + + /** + * @param iterable ...$iterables + */ + public function __construct(iterable ...$iterables) + { + foreach ($iterables as $iterable) { + $this->iterators[] = Iter::makeIterator($iterable); + } + } + + /** + * {@inheritDoc} + * + * @return array + */ + public function current(): array + { + return array_map( + static function (\Iterator $iterator) { + return $iterator->valid() ? $iterator->current() : NoValueMonad::getInstance(); + }, + $this->iterators + ); + } + + /** + * {@inheritDoc} + */ + public function next(): void + { + foreach ($this->iterators as $iterator) { + if ($iterator->valid()) { + $iterator->next(); + } + } + $this->index++; + } + + /** + * {@inheritDoc} + * + * @return int + */ + public function key(): int + { + return $this->index; + } + + /** + * {@inheritDoc} + */ + public function valid(): bool + { + foreach ($this->iterators as $iterator) { + if ($iterator->valid()) { + return true; + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function rewind(): void + { + foreach ($this->iterators as $iterator) { + $iterator->rewind(); + } + $this->index = 0; + } +} diff --git a/src/Util/NoValueMonad.php b/src/Util/NoValueMonad.php new file mode 100644 index 000000000..86e1ee0e9 --- /dev/null +++ b/src/Util/NoValueMonad.php @@ -0,0 +1,29 @@ +assertEquals($expected->asArray(), $A∩B->asArray()); } + /** + * @test + * @dataProvider dataProviderForIntersectPartial + */ + public function testIntersectPartial(array $A, array $B, int $m, array $Amp∩B, Set $R) + { + // Given + $setA = new Set($A); + $setB = new Set($B); + $expected = new Set($Amp∩B); + + // When + $intersection = $setA->intersectPartial($m, $setB); + $intersection_array = $intersection->asArray(); + + // Then + $this->assertEquals($R, $intersection); + $this->assertEquals($expected, $intersection); + $this->assertEquals(count($Amp∩B), count($intersection)); + foreach ($Amp∩B as $member) { + $this->assertArrayHasKey("$member", $intersection_array); + } + foreach ($Amp∩B as $_ => $value) { + if ($value instanceof Set) { + $this->assertEquals($value, $intersection_array["$value"]); + } else { + $this->assertContains($value, $intersection_array); + } + } + } + + public function dataProviderForIntersectPartial(): array + { + $setOneTwo = new Set([1, 2]); + + return [ + [ + [], + [], + 1, + [], + new Set(), + ], + [ + [], + [], + 2, + [], + new Set(), + ], + [ + [], + [], + 3, + [], + new Set(), + ], + [ + [1], + [], + 1, + [1], + new Set([1]), + ], + [ + [1], + [], + 2, + [], + new Set(), + ], + [ + [1], + [], + 3, + [], + new Set(), + ], + [ + [], + [1], + 1, + [1], + new Set([1]), + ], + [ + [], + [1], + 2, + [], + new Set(), + ], + [ + [], + [1], + 3, + [], + new Set(), + ], + [ + [1], + [1], + 1, + [1], + new Set([1]), + ], + [ + [1], + [1], + 2, + [1], + new Set([1]), + ], + [ + [1], + [1], + 3, + [], + new Set(), + ], + [ + [1], + [2], + 1, + [1, 2], + new Set([1, 2]), + ], + [ + [1], + [2], + 2, + [], + new Set([]), + ], + [ + [1], + [2], + 3, + [], + new Set([]), + ], + [ + [2], + [1], + 1, + [1, 2], + new Set([1, 2]), + ], + [ + [2], + [1], + 2, + [], + new Set([]), + ], + [ + [2], + [1], + 3, + [], + new Set([]), + ], + [ + [2], + [2], + 1, + [2], + new Set([2]), + ], + [ + [2], + [2], + 2, + [2], + new Set([2]), + ], + [ + [2], + [2], + 3, + [], + new Set(), + ], + [ + [1, 2], + [1, 2], + 1, + [1, 2], + new Set([1, 2]), + ], + [ + [1, 2], + [1, 2], + 2, + [1, 2], + new Set([1, 2]), + ], + [ + [1, 2], + [1, 2], + 3, + [], + new Set(), + ], + [ + [1, 2], + [2, 1], + 1, + [1, 2], + new Set([1, 2]), + ], + [ + [1, 2], + [2, 1], + 2, + [1, 2], + new Set([1, 2]), + ], + [ + [1, 2], + [2, 1], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k'], + 1, + [1, 2, 3, 'a', 'b', 'k'], + new Set([1, 2, 3, 'a', 'b', 'k']), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k'], + 2, + [1, 'a'], + new Set([1, 'a']), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k'], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b', new Set([1, 2])], + [1, 'a', 'k'], + 1, + [1, 2, 3, 'a', 'b', 'k', $setOneTwo], + new Set([1, 2, 3, 'a', 'b', 'k', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', new Set([1, 2])], + [1, 'a', 'k'], + 2, + [1, 'a'], + new Set([1, 'a']), + ], + [ + [1, 2, 3, 'a', 'b', new Set([1, 2])], + [1, 'a', 'k'], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k', new Set([1, 2])], + 1, + [1, 2, 3, 'a', 'b', 'k', $setOneTwo], + new Set([1, 2, 3, 'a', 'b', 'k', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k', new Set([1, 2])], + 2, + [1, 'a'], + new Set([1, 'a']), + ], + [ + [1, 2, 3, 'a', 'b'], + [1, 'a', 'k', new Set([1, 2])], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', $setOneTwo], + 1, + [1, 2, 3, 'a', 'b', 'k', $setOneTwo], + new Set([1, 2, 3, 'a', 'b', 'k', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', $setOneTwo], + 2, + [1, 'a', $setOneTwo], + new Set([1, 'a', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', $setOneTwo], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b', new Set()], + [1, 'a', 'k', $setOneTwo], + 1, + [1, 2, 3, 'a', 'b', 'k', new Set(), $setOneTwo], + new Set([1, 2, 3, 'a', 'b', 'k', new Set(), $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', new Set()], + [1, 'a', 'k', $setOneTwo], + 2, + [1, 'a'], + new Set([1, 'a']), + ], + [ + [1, 2, 3, 'a', 'b', new Set()], + [1, 'a', 'k', $setOneTwo], + 3, + [], + new Set(), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', 3.5, -2, '2.4', $setOneTwo], + 1, + [-2, 1, 2, 3, 3.5, '2.4', 'a', 'b', 'k', $setOneTwo], + new Set([-2, 1, 2, 3, 3.5, '2.4', 'a', 'b', 'k', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', -2, '2.4', 3.5, $setOneTwo], + 2, + [1, 'a', $setOneTwo], + new Set([1, 'a', $setOneTwo]), + ], + [ + [1, 2, 3, 'a', 'b', $setOneTwo], + [1, 'a', 'k', -2, '2.4', 3.5, $setOneTwo], + 3, + [], + new Set(), + ], + ]; + } + /** * @test * @dataProvider dataProviderForDifference From dbfb01ea31d34863057c9733f0587de38b1139b2 Mon Sep 17 00:00:00 2001 From: Smoren Date: Thu, 26 Jan 2023 17:17:19 +0300 Subject: [PATCH 2/9] `Set::intersectPartial()`: new test cases added. --- tests/SetTheory/SetOperationsTest.php | 114 ++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/tests/SetTheory/SetOperationsTest.php b/tests/SetTheory/SetOperationsTest.php index 97dc884d8..94da2296f 100644 --- a/tests/SetTheory/SetOperationsTest.php +++ b/tests/SetTheory/SetOperationsTest.php @@ -1528,12 +1528,12 @@ public function testIntersectWithObjects2() * @test * @dataProvider dataProviderForIntersectPartial */ - public function testIntersectPartial(array $A, array $B, int $m, array $Amp∩B, Set $R) + public function testIntersectPartial(array $A, array $B, int $m, array $mpA∩B, Set $R) { // Given $setA = new Set($A); $setB = new Set($B); - $expected = new Set($Amp∩B); + $expected = new Set($mpA∩B); // When $intersection = $setA->intersectPartial($m, $setB); @@ -1542,11 +1542,11 @@ public function testIntersectPartial(array $A, array $B, int $m, array $Amp∩B, // Then $this->assertEquals($R, $intersection); $this->assertEquals($expected, $intersection); - $this->assertEquals(count($Amp∩B), count($intersection)); - foreach ($Amp∩B as $member) { + $this->assertEquals(count($mpA∩B), count($intersection)); + foreach ($mpA∩B as $member) { $this->assertArrayHasKey("$member", $intersection_array); } - foreach ($Amp∩B as $_ => $value) { + foreach ($mpA∩B as $_ => $value) { if ($value instanceof Set) { $this->assertEquals($value, $intersection_array["$value"]); } else { @@ -1878,6 +1878,110 @@ public function dataProviderForIntersectPartial(): array ]; } + /** + * @test + * @dataProvider dataProviderForIntersectPartialMultipleSets + */ + public function testIntersectPartialMultipleSets(array $A, array $B, array $C, int $m, array $mpA∩B∩C, Set $R) + { + // Given + $setA = new Set($A); + $setB = new Set($B); + $setC = new Set($C); + $expected = new Set($mpA∩B∩C); + + // When + $intersection = $setA->intersectPartial($m, $setB, $setC); + $intersection_array = $intersection->asArray(); + + // Then + $this->assertEquals($R, $intersection); + $this->assertEquals($expected, $intersection); + $this->assertEquals(count($mpA∩B∩C), count($intersection)); + foreach ($mpA∩B∩C as $member) { + $this->assertArrayHasKey("$member", $intersection_array); + } + foreach ($mpA∩B∩C as $_ => $value) { + if ($value instanceof Set) { + $this->assertEquals($value, $intersection_array["$value"]); + } else { + $this->assertContains($value, $intersection_array); + } + } + } + + public function dataProviderForIntersectPartialMultipleSets(): array + { + $setOneTwo = new Set([1, 2]); + + return [ + [ + [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + 1, + [1, 2, 3, 4, 5, 6], + new Set([1, 2, 3, 4, 5, 6]), + ], + [ + [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + 2, + [2, 3, 4, 5], + new Set([2, 3, 4, 5]), + ], + [ + [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + 3, + [3, 4], + new Set([3, 4]), + ], + [ + [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + 4, + [], + new Set([]), + ], + [ + [1, 2, 3, 4, $setOneTwo], + [2, 3, 4, 5, $setOneTwo], + [3, 4, 5, 6, $setOneTwo], + 1, + [1, 2, 3, 4, 5, 6, $setOneTwo], + new Set([1, 2, 3, 4, 5, 6, $setOneTwo]), + ], + [ + [1, 2, 3, 4, $setOneTwo], + [2, 3, 4, 5, $setOneTwo], + [3, 4, 5, 6, $setOneTwo], + 2, + [2, 3, 4, 5, $setOneTwo], + new Set([2, 3, 4, 5, $setOneTwo]), + ], + [ + [1, 2, 3, 4, $setOneTwo], + [2, 3, 4, 5, $setOneTwo], + [3, 4, 5, 6, $setOneTwo], + 3, + [3, 4, $setOneTwo], + new Set([3, 4, $setOneTwo]), + ], + [ + [1, 2, 3, 4, $setOneTwo], + [2, 3, 4, 5, $setOneTwo], + [3, 4, 5, 6, $setOneTwo], + 4, + [], + new Set(), + ], + ]; + } + /** * @test * @dataProvider dataProviderForDifference From a35c1003a13b303cf66710dee41ac7235e29e298 Mon Sep 17 00:00:00 2001 From: Smoren Date: Thu, 26 Jan 2023 19:07:07 +0300 Subject: [PATCH 3/9] PHPdoc and README are updated with description of M-partial intersection of the sets --- README.md | 1 + src/SetTheory/Set.php | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f0c29298..c7994660f 100644 --- a/README.md +++ b/README.md @@ -1868,6 +1868,7 @@ $bool = $A->isProperSuperset($B); // A ⊇ B & A ≠ B // Set operations with other sets - return a new Set $A∪B = $A->union($B); $A∩B = $A->intersect($B); +$A∩B = $A->intersectPartial(2, $B); // M-partial intersection $A\B = $A->difference($B); // relative complement $AΔB = $A->symmetricDifference($B); $A×B = $A->cartesianProduct($B); diff --git a/src/SetTheory/Set.php b/src/SetTheory/Set.php index 5c11d85ae..24c5a5322 100644 --- a/src/SetTheory/Set.php +++ b/src/SetTheory/Set.php @@ -377,6 +377,7 @@ public function isProperSuperset(Set $B): bool * SET OPERATIONS ON OTHER SETS * - Union * - Intersection + * - Partial intersection * - Difference * - Symmetric difference **************************************************************************/ @@ -432,7 +433,21 @@ public function intersect(Set ...$Bs): Set } /** - * TODO add + * Produces a new set of the M-partial intersection of this set and another given sets. + * + * Definition: + * + * An M-partial intersection (for M > 0) of N sets is a set elements in which + * are contained in at least M initial sets. + * + * Properties: + * + * - 1-partial intersection is equivalent to the union of these sets. + * - 2-partial intersection is equivalent to the difference of the union and the symmetric difference of these sets. + * - N-partial intersection is equivalent to the common (complete) intersection of these sets. + * - For any M > N M-partial intersection always equals to the empty set. + * + * @see https://github.com/Smoren/partial-intersection-php for the explanation and the examples. * * @param int $m Min intersection count * @param Set ...$Bs One or more sets From 7a62eb3d537f2b3d954155434cdcba92ea479faa Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 00:14:46 +0300 Subject: [PATCH 4/9] `Set::intersectPartial()`: new test cases added. --- tests/SetTheory/SetOperationsTest.php | 269 +++++++++++++++++++++++++- 1 file changed, 261 insertions(+), 8 deletions(-) diff --git a/tests/SetTheory/SetOperationsTest.php b/tests/SetTheory/SetOperationsTest.php index 94da2296f..f2a9ef112 100644 --- a/tests/SetTheory/SetOperationsTest.php +++ b/tests/SetTheory/SetOperationsTest.php @@ -1656,14 +1656,14 @@ public function dataProviderForIntersectPartial(): array [2], 2, [], - new Set([]), + new Set(), ], [ [1], [2], 3, [], - new Set([]), + new Set(), ], [ [2], @@ -1677,14 +1677,14 @@ public function dataProviderForIntersectPartial(): array [1], 2, [], - new Set([]), + new Set(), ], [ [2], [1], 3, [], - new Set([]), + new Set(), ], [ [2], @@ -1898,9 +1898,6 @@ public function testIntersectPartialMultipleSets(array $A, array $B, array $C, i $this->assertEquals($R, $intersection); $this->assertEquals($expected, $intersection); $this->assertEquals(count($mpA∩B∩C), count($intersection)); - foreach ($mpA∩B∩C as $member) { - $this->assertArrayHasKey("$member", $intersection_array); - } foreach ($mpA∩B∩C as $_ => $value) { if ($value instanceof Set) { $this->assertEquals($value, $intersection_array["$value"]); @@ -1914,6 +1911,22 @@ public function dataProviderForIntersectPartialMultipleSets(): array { $setOneTwo = new Set([1, 2]); + $gen = static function (array $data) { + return static function () use ($data) { + foreach ($data as $datum) { + yield $datum; + } + }; + }; + $res = static function () { + return fopen('php://input', 'r'); + }; + $clos = static function () { + return static function () { + return 0; + }; + }; + return [ [ [1, 2, 3, 4], @@ -1945,7 +1958,7 @@ public function dataProviderForIntersectPartialMultipleSets(): array [3, 4, 5, 6], 4, [], - new Set([]), + new Set(), ], [ [1, 2, 3, 4, $setOneTwo], @@ -1979,6 +1992,246 @@ public function dataProviderForIntersectPartialMultipleSets(): array [], new Set(), ], + [ + ['c++', 'java', 'c#', 'go', 'haskell'], + ['php', 'python', 'javascript', 'perl'], + ['c++', 'java', 'c#', 'go', 'php'], + 1, + ['c++', 'java', 'c#', 'go', 'haskell', 'php', 'python', 'javascript', 'perl'], + new Set(['c++', 'java', 'c#', 'go', 'haskell', 'php', 'python', 'javascript', 'perl']), + ], + [ + ['c++', 'java', 'c#', 'go', 'haskell'], + ['php', 'python', 'javascript', 'perl'], + ['c++', 'java', 'c#', 'go', 'php'], + 2, + ['c++', 'java', 'c#', 'go', 'php'], + new Set(['c++', 'java', 'c#', 'go', 'php']), + ], + [ + ['c++', 'java', 'c#', 'go', 'haskell'], + ['php', 'python', 'javascript', 'perl'], + ['c++', 'java', 'c#', 'go', 'php'], + 3, + [], + new Set(), + ], + [ + ['c++', 'java', 'c#', 'go', 'haskell'], + ['php', 'python', 'javascript', 'perl'], + ['c++', 'java', 'c#', 'go', 'php'], + 4, + [], + new Set(), + ], + [ + [1, 2, 3, 4, 5], + [1, 2, '3', '4'], + [4, 5, 6, 7, '8', '9'], + 1, + [1, 2, 3, 4, 5, 6, 7, '8', '9'], + new Set([1, 2, 3, 4, 5, 6, 7, '8', '9']), + ], + [ + [1, 2, 3, 4, 5], + [1, 2, '3', '4'], + [4, 5, 6, 7, '8', '9'], + 2, + [1, 2, 3, 4, 5], + new Set([1, 2, 3, 4, 5]), + ], + [ + [1, 2, 3, 4, 5], + [1, 2, '3', '4'], + [4, 5, 6, 7, '8', '9'], + 3, + [4], + new Set([4]), + ], + [ + [1, 2, 3, 4, 5], + [1, 2, '3', '4'], + [4, 5, 6, 7, '8', '9'], + 4, + [], + new Set(), + ], + [ + [[1], [2], [3], [4], [5]], + [[2], [3], [4], [5], [6]], + [[3], [4], [5], [6], [7]], + 1, + [[1], [2], [3], [4], [5], [6], [7]], + new Set([[1], [2], [3], [4], [5], [6], [7]]), + ], + [ + [[1], [2], [3], [4], [5]], + [[2], [3], [4], [5], [6]], + [[3], [4], [5], [6], [7]], + 2, + [[2], [3], [4], [5], [6]], + new Set([[2], [3], [4], [5], [6]]), + ], + [ + [[1], [2], [3], [4], [5]], + [[2], [3], [4], [5], [6]], + [[3], [4], [5], [6], [7]], + 3, + [[3], [4], [5]], + new Set([[3], [4], [5]]), + ], + [ + [[1], [2], [3], [4], [5]], + [[2], [3], [4], [5], [6]], + [[3], [4], [5], [6], [7]], + 4, + [], + new Set(), + ], + [ + [$o1 = (object)[1], $o2 = (object)[2], $o3 = (object)[3], $o4 = (object)[4], $o5 = (object)[5]], + [$o2, $o3, $o4, $o5, $o6 = (object)[6]], + [$o3, $o4, $o5, $o6, $o7 = (object)[7]], + 1, + [$o1, $o2, $o3, $o4, $o5, $o6, $o7], + new Set([$o1, $o2, $o3, $o4, $o5, $o6, $o7]), + ], + [ + [(object)[1], $o2 = (object)[2], $o3 = (object)[3], $o4 = (object)[4], $o5 = (object)[5]], + [$o2, $o3, $o4, $o5, $o6 = (object)[6]], + [$o3, $o4, $o5, $o6, (object)[7]], + 2, + [$o2, $o3, $o4, $o5, $o6], + new Set([$o2, $o3, $o4, $o5, $o6]), + ], + [ + [(object)[1], $o2 = (object)[2], $o3 = (object)[3], $o4 = (object)[4], $o5 = (object)[5]], + [$o2, $o3, $o4, $o5, $o6 = (object)[6]], + [$o3, $o4, $o5, $o6, (object)[7]], + 3, + [$o3, $o4, $o5], + new Set([$o3, $o4, $o5]), + ], + [ + [(object)[1], $o2 = (object)[2], $o3 = (object)[3], $o4 = (object)[4], $o5 = (object)[5]], + [$o2, $o3, $o4, $o5, $o6 = (object)[6]], + [$o3, $o4, $o5, $o6, (object)[7]], + 4, + [], + new Set(), + ], + [ + [$o1 = $gen([]), $o2 = $gen([]), $o3 = $gen([]), $o4 = $gen([]), $o5 = $gen([])], + [$o2, $o3, $o4, $o5, $o6 = $gen([])], + [$o3, $o4, $o5, $o6, $o7 = $gen([])], + 1, + [$o1, $o2, $o3, $o4, $o5, $o6, $o7], + new Set([$o1, $o2, $o3, $o4, $o5, $o6, $o7]), + ], + [ + [$gen([]), $o2 = $gen([]), $o3 = $gen([]), $o4 = $gen([]), $o5 = $gen([])], + [$o2, $o3, $o4, $o5, $o6 = $gen([])], + [$o3, $o4, $o5, $o6, $gen([])], + 2, + [$o2, $o3, $o4, $o5, $o6], + new Set([$o2, $o3, $o4, $o5, $o6]), + ], + [ + [$gen([]), $o2 = $gen([]), $o3 = $gen([]), $o4 = $gen([]), $o5 = $gen([])], + [$o2, $o3, $o4, $o5, $o6 = $gen([])], + [$o3, $o4, $o5, $o6, $gen([])], + 3, + [$o3, $o4, $o5], + new Set([$o3, $o4, $o5]), + ], + [ + [$gen([]), $o2 = $gen([]), $o3 = $gen([]), $o4 = $gen([]), $o5 = $gen([])], + [$o2, $o3, $o4, $o5, $o6 = $gen([])], + [$o3, $o4, $o5, $o6, $gen([])], + 4, + [], + new Set(), + ], + [ + [$o1 = $res(), $o2 = $res(), $o3 = $res(), $o4 = $res(), $o5 = $res()], + [$o2, $o3, $o4, $o5, $o6 = $res()], + [$o3, $o4, $o5, $o6, $o7 = $res()], + 1, + [$o1, $o2, $o3, $o4, $o5, $o6, $o7], + new Set([$o1, $o2, $o3, $o4, $o5, $o6, $o7]), + ], + [ + [$res(), $o2 = $res(), $o3 = $res(), $o4 = $res(), $o5 = $res()], + [$o2, $o3, $o4, $o5, $o6 = $res()], + [$o3, $o4, $o5, $o6, $res()], + 2, + [$o2, $o3, $o4, $o5, $o6], + new Set([$o2, $o3, $o4, $o5, $o6]), + ], + [ + [$res(), $o2 = $res(), $o3 = $res(), $o4 = $res(), $o5 = $res()], + [$o2, $o3, $o4, $o5, $o6 = $res()], + [$o3, $o4, $o5, $o6, $res()], + 3, + [$o3, $o4, $o5], + new Set([$o3, $o4, $o5]), + ], + [ + [$res(), $o2 = $res(), $o3 = $res(), $o4 = $res(), $o5 = $res()], + [$o2, $o3, $o4, $o5, $o6 = $res()], + [$o3, $o4, $o5, $o6, $res()], + 4, + [], + new Set(), + ], + [ + [$o1 = $clos(), $o2 = $clos(), $o3 = $clos(), $o4 = $clos(), $o5 = $clos()], + [$o2, $o3, $o4, $o5, $o6 = $clos()], + [$o3, $o4, $o5, $o6, $o7 = $clos()], + 1, + [$o1, $o2, $o3, $o4, $o5, $o6, $o7], + new Set([$o1, $o2, $o3, $o4, $o5, $o6, $o7]), + ], + [ + [$clos(), $o2 = $clos(), $o3 = $clos(), $o4 = $clos(), $o5 = $clos()], + [$o2, $o3, $o4, $o5, $o6 = $clos()], + [$o3, $o4, $o5, $o6, $clos()], + 2, + [$o2, $o3, $o4, $o5, $o6], + new Set([$o2, $o3, $o4, $o5, $o6]), + ], + [ + [$clos(), $o2 = $clos(), $o3 = $clos(), $o4 = $clos(), $o5 = $clos()], + [$o2, $o3, $o4, $o5, $o6 = $clos()], + [$o3, $o4, $o5, $o6, $clos()], + 3, + [$o3, $o4, $o5], + new Set([$o3, $o4, $o5]), + ], + [ + [$clos(), $o2 = $clos(), $o3 = $clos(), $o4 = $clos(), $o5 = $clos()], + [$o2, $o3, $o4, $o5, $o6 = $clos()], + [$o3, $o4, $o5, $o6, $clos()], + 4, + [], + new Set(), + ], + [ + [null, 1, 2, 3], + [1, 2, 3, 4, 5], + [2, 3, 4], + 2, + [1, 2, 3, 4], + new Set([1, 2, 3, 4]), + ], + [ + [null, 1, 2, 3], + [null, 1, 2, 3, 4, 5], + [2, 3, 4], + 2, + [null, 1, 2, 3, 4], + new Set([null, 1, 2, 3, 4]), + ], ]; } From 11ba945dcbf3e9353d6e00116a7c1b0bed4dac96 Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 10:00:52 +0300 Subject: [PATCH 5/9] `SetOperationsTest::testIntersectPartialMultipleSets()` fix. --- tests/SetTheory/SetOperationsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SetTheory/SetOperationsTest.php b/tests/SetTheory/SetOperationsTest.php index f2a9ef112..482fb322f 100644 --- a/tests/SetTheory/SetOperationsTest.php +++ b/tests/SetTheory/SetOperationsTest.php @@ -1902,7 +1902,7 @@ public function testIntersectPartialMultipleSets(array $A, array $B, array $C, i if ($value instanceof Set) { $this->assertEquals($value, $intersection_array["$value"]); } else { - $this->assertContains($value, $intersection_array); + $this->assertTrue(in_array($value, $intersection_array)); } } } From 30c6184ef325cd808d4cf5a3ff769b35ec5ee84c Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 10:32:47 +0300 Subject: [PATCH 6/9] `SetAxiomsTest`: test cases for partial intersections were added. --- tests/SetTheory/SetAxiomsTest.php | 70 +++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/SetTheory/SetAxiomsTest.php b/tests/SetTheory/SetAxiomsTest.php index d8325b532..be4d3c7a5 100644 --- a/tests/SetTheory/SetAxiomsTest.php +++ b/tests/SetTheory/SetAxiomsTest.php @@ -728,4 +728,74 @@ public function testCardinalityOfPowerSet(Set $A) $this->assertEquals(\pow(2, $n), count($P⟮S⟯)); $this->assertEquals(\pow(2, $n), count($P⟮S⟯->asArray())); } + + /** + * @test + * @dataProvider dataProviderForOnePartialIntersectionIsUnion + * @param Set $s + * @param Set ...$others + * @return void + */ + public function testOnePartialIntersectionIsUnion(Set $s, Set ...$others) + { + // Given + $union = $s->union(...$others); + $onePartialIntersection = $s->intersectPartial(1, ...$others); + + // Then + $this->assertEquals($union, $onePartialIntersection); + } + + public function dataProviderForOnePartialIntersectionIsUnion(): array + { + return [ + [ + new Set(), + new Set(), + ], + [ + new Set(), + new Set(), + new Set(), + ], + [ + new Set([1]), + new Set(), + ], + [ + new Set(), + new Set([1]), + ], + [ + new Set([1]), + new Set([1]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + ]; + } } From 6f89740fb6159819f09262b1fdb9ea68970535b4 Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 13:39:41 +0300 Subject: [PATCH 7/9] `Set::partialIntersection()`: all the axiomatic unit tests added. - testPartialIntersectionDefinition(); - testOnePartialIntersectionIsUnion(); - testTwoPartialIntersectionIsDifferenceOfUnionAndSymmetricDifference(); - testNPartialIntersectionIsCompleteIntersection(); - testNPartialIntersectionIsEmptySetWhenMMoreThanN(). --- tests/SetTheory/SetAxiomsTest.php | 609 +++++++++++++++++++++++++++++- 1 file changed, 608 insertions(+), 1 deletion(-) diff --git a/tests/SetTheory/SetAxiomsTest.php b/tests/SetTheory/SetAxiomsTest.php index be4d3c7a5..426f3d23c 100644 --- a/tests/SetTheory/SetAxiomsTest.php +++ b/tests/SetTheory/SetAxiomsTest.php @@ -730,6 +730,272 @@ public function testCardinalityOfPowerSet(Set $A) } /** + * An M-partial intersection (for M > 0) of N sets is a set elements in which + * are contained in at least M initial sets. + * + * @test + * @dataProvider dataProviderForPartialIntersectionDefinition + * @param int $m + * @param Set ...$sets + * @return void + */ + public function testPartialIntersectionDefinition(int $m, Set ...$sets) + { + // Given + $allSets = $sets; + $s = array_shift($sets); + + // When + $partialIntersection = $s->intersectPartial($m, ...$sets); + + // Then + foreach ($partialIntersection as $value) { + $usageCount = array_reduce($allSets, static function (int $carry, Set $currentSet) use ($value) { + return $carry + intval($currentSet->isMember($value)); + }, 0); + + // Assert that every element in M-partial intersection occurs in at least M sets. + $this->assertTrue($usageCount >= $m); + } + + // Then + foreach ($allSets as $set) { + $notInPartialIntersection = $set->difference($partialIntersection); + foreach ($notInPartialIntersection as $value) { + $usageCount = array_reduce($allSets, static function (int $carry, Set $currentSet) use ($value) { + return $carry + intval($currentSet->isMember($value)); + }, 0); + + // Assert that elements from sets and not in M-partial intersection occurs in less than M sets. + $this->assertTrue($usageCount < $m); + } + } + } + + public function dataProviderForPartialIntersectionDefinition(): array + { + return [ + [ + 1, + new Set([1]), + ], + [ + 2, + new Set([1]), + ], + [ + 1, + new Set([1]), + new Set(), + ], + [ + 2, + new Set([1]), + new Set(), + ], + [ + 1, + new Set(), + new Set([1]), + ], + [ + 2, + new Set(), + new Set([1]), + ], + [ + 1, + new Set([1]), + new Set([1]), + ], + [ + 2, + new Set([1]), + new Set([1]), + ], + [ + 3, + new Set([1]), + new Set([1]), + ], + [ + 1, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + 2, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + 1, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + 2, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + 1, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 2, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 1, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 2, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 1, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 2, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 3, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 4, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 1, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 2, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 3, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 4, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 5, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 1, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 2, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 3, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 4, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 5, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + ]; + } + + /** + * 1-partial intersection is equivalent to the union of these sets. + * * @test * @dataProvider dataProviderForOnePartialIntersectionIsUnion * @param Set $s @@ -739,9 +1005,11 @@ public function testCardinalityOfPowerSet(Set $A) public function testOnePartialIntersectionIsUnion(Set $s, Set ...$others) { // Given - $union = $s->union(...$others); $onePartialIntersection = $s->intersectPartial(1, ...$others); + // When + $union = $s->union(...$others); + // Then $this->assertEquals($union, $onePartialIntersection); } @@ -774,23 +1042,362 @@ public function dataProviderForOnePartialIntersectionIsUnion(): array new Set([1, 2, 3, 4, 5]), new Set([2, 3, 4, 5, 6]), ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], [ new Set([1, 2, 3, 4, 5]), new Set([2, 3, 4, 5, 6]), new Set([3, 4, 5, 6, 7]), ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], [ new Set([1, 2, 3]), new Set([2, 3, 4, 5]), new Set([3, 4, 5, 6, 7]), + new Set(), ], [ new Set([1, 2, 3]), new Set([2, 3, 4, 5]), new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + ]; + } + + /** + * 2-partial intersection is equivalent to the difference of the union and the symmetric difference of these sets. + * + * @test + * @dataProvider dataProviderForTwoPartialIntersectionIsDifferenceOfUnionAndSymmetricDifference + * @param Set $lhs + * @param Set $rhs + */ + public function testTwoPartialIntersectionIsDifferenceOfUnionAndSymmetricDifference(Set $lhs, Set $rhs) + { + // Given + $onePartialIntersection = $lhs->intersectPartial(2, $rhs); + + // When + $union = $lhs->union($rhs); + $symmetricDifference = $lhs->symmetricDifference($rhs); + $diffOfUnionAndSymmetricDifference = $union->difference($symmetricDifference); + + // Then + $this->assertEquals($diffOfUnionAndSymmetricDifference, $onePartialIntersection); + } + + public function dataProviderForTwoPartialIntersectionIsDifferenceOfUnionAndSymmetricDifference(): array + { + return [ + [ + new Set(), new Set(), ], [ + new Set(), + new Set(), + new Set(), + ], + [ + new Set([1]), + new Set(), + ], + [ + new Set(), + new Set([1]), + ], + [ + new Set([1]), + new Set([1]), + ], + [ + new Set(), + new Set([1, 2, 3]), + ], + [ + new Set([1, 2, 3]), + new Set(), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + ], + ]; + } + + /** + * N-partial intersection is equivalent to the common (complete) intersection of these sets. + * + * @test + * @dataProvider dataProviderForNPartialIntersectionIsCompleteIntersection + * @param Set $s + * @param Set ...$others + * @return void + */ + public function testNPartialIntersectionIsCompleteIntersection(Set $s, Set ...$others) + { + // Given + $n = count($others) + 1; + $onePartialIntersection = $s->intersectPartial($n, ...$others); + + // When + $union = $s->intersect(...$others); + + // Then + $this->assertEquals($union, $onePartialIntersection); + } + + public function dataProviderForNPartialIntersectionIsCompleteIntersection(): array + { + return [ + [ + new Set(), + new Set(), + ], + [ + new Set(), + new Set(), + new Set(), + ], + [ + new Set([1]), + new Set(), + ], + [ + new Set(), + new Set([1]), + ], + [ + new Set([1]), + new Set([1]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + ]; + } + + /** + * For any M > N M-partial intersection always equals to the empty set. + * + * @test + * @dataProvider dataProviderForNPartialIntersectionIsEmptySetWhenMMoreThanN + * @param int $m + * @param Set $s + * @param Set ...$others + * @return void + */ + public function testNPartialIntersectionIsEmptySetWhenMMoreThanN(int $m, Set $s, Set ...$others) + { + // Given + $emptySet = new Set(); + $n = count($others) + 1; + + // When + $this->assertTrue($m > $n); + $partialIntersection = $s->intersectPartial($m, ...$others); + + // Then + $this->assertEquals($emptySet, $partialIntersection); + } + + public function dataProviderForNPartialIntersectionIsEmptySetWhenMMoreThanN(): array + { + return [ + [ + 3, + new Set(), + new Set(), + ], + [ + 4, + new Set(), + new Set(), + ], + [ + 4, + new Set(), + new Set(), + new Set(), + ], + [ + 5, + new Set(), + new Set(), + new Set(), + ], + [ + 3, + new Set([1]), + new Set(), + ], + [ + 4, + new Set([1]), + new Set(), + ], + [ + 3, + new Set(), + new Set([1]), + ], + [ + 4, + new Set(), + new Set([1]), + ], + [ + 3, + new Set([1]), + new Set([1]), + ], + [ + 4, + new Set([1]), + new Set([1]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + ], + [ + 3, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 5, + new Set([1, 2, 3, 4, 5]), + new Set([2, 3, 4, 5, 6]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 4, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 5, + new Set([1, 2, 3, 4, 5]), + new Set([6, 7, 8, 9, 10]), + new Set([11, 12, 13, 14, 15]), + ], + [ + 4, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 5, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + ], + [ + 5, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 6, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set(), + ], + [ + 5, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 6, + new Set([1, 2, 3]), + new Set([2, 3, 4, 5]), + new Set([3, 4, 5, 6, 7]), + new Set([3, 4, 5, 6, 7, 8]), + ], + [ + 100, new Set([1, 2, 3]), new Set([2, 3, 4, 5]), new Set([3, 4, 5, 6, 7]), From 15c095c7240189ed711edceddfbede5b433c4e3c Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 14:41:24 +0300 Subject: [PATCH 8/9] `SetAxiomsTest`: new test cases added. --- tests/SetTheory/SetAxiomsTest.php | 92 ++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/tests/SetTheory/SetAxiomsTest.php b/tests/SetTheory/SetAxiomsTest.php index 426f3d23c..14427e958 100644 --- a/tests/SetTheory/SetAxiomsTest.php +++ b/tests/SetTheory/SetAxiomsTest.php @@ -744,9 +744,17 @@ public function testPartialIntersectionDefinition(int $m, Set ...$sets) // Given $allSets = $sets; $s = array_shift($sets); + $totalElementsCount = array_reduce($allSets, static function (int $carry, Set $set) { + return $carry + count($set); + }, 0); + $partialIntersection = $s->intersectPartial($m, ...$sets); // When - $partialIntersection = $s->intersectPartial($m, ...$sets); + if ($totalElementsCount === 0) { + // Then + // Assert than for any M and N M-partial intersection of N empty sets is an empty set. + $this->assertCount(0, $partialIntersection); + } // Then foreach ($partialIntersection as $value) { @@ -775,6 +783,14 @@ public function testPartialIntersectionDefinition(int $m, Set ...$sets) public function dataProviderForPartialIntersectionDefinition(): array { return [ + [ + 1, + new Set(), + ], + [ + 2, + new Set(), + ], [ 1, new Set([1]), @@ -783,6 +799,21 @@ public function dataProviderForPartialIntersectionDefinition(): array 2, new Set([1]), ], + [ + 1, + new Set(), + new Set(), + ], + [ + 2, + new Set(), + new Set(), + ], + [ + 3, + new Set(), + new Set(), + ], [ 1, new Set([1]), @@ -848,6 +879,30 @@ public function dataProviderForPartialIntersectionDefinition(): array new Set([1, 2, 3, 4, 5]), new Set([6, 7, 8, 9, 10]), ], + [ + 1, + new Set(), + new Set(), + new Set(), + ], + [ + 2, + new Set(), + new Set(), + new Set(), + ], + [ + 3, + new Set(), + new Set(), + new Set(), + ], + [ + 4, + new Set(), + new Set(), + new Set(), + ], [ 1, new Set([1, 2, 3, 4, 5]), @@ -920,6 +975,41 @@ public function dataProviderForPartialIntersectionDefinition(): array new Set([2, 3, 4, 5]), new Set([3, 4, 5, 6, 7]), ], + [ + 1, + new Set(), + new Set(), + new Set(), + new Set(), + ], + [ + 2, + new Set(), + new Set(), + new Set(), + new Set(), + ], + [ + 3, + new Set(), + new Set(), + new Set(), + new Set(), + ], + [ + 4, + new Set(), + new Set(), + new Set(), + new Set(), + ], + [ + 5, + new Set(), + new Set(), + new Set(), + new Set(), + ], [ 1, new Set([1, 2, 3]), From f5a52dc7042094ff59a5952f1893a6cbeb031596 Mon Sep 17 00:00:00 2001 From: Smoren Date: Fri, 27 Jan 2023 18:23:37 +0300 Subject: [PATCH 9/9] `SetAxiomTest`: naming fix. --- tests/SetTheory/SetAxiomsTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/SetTheory/SetAxiomsTest.php b/tests/SetTheory/SetAxiomsTest.php index 14427e958..2445b1aeb 100644 --- a/tests/SetTheory/SetAxiomsTest.php +++ b/tests/SetTheory/SetAxiomsTest.php @@ -1327,13 +1327,13 @@ public function dataProviderForNPartialIntersectionIsCompleteIntersection(): arr * For any M > N M-partial intersection always equals to the empty set. * * @test - * @dataProvider dataProviderForNPartialIntersectionIsEmptySetWhenMMoreThanN + * @dataProvider dataProviderForMPartialIntersectionIsEmptySetWhenMMoreThanN * @param int $m * @param Set $s * @param Set ...$others * @return void */ - public function testNPartialIntersectionIsEmptySetWhenMMoreThanN(int $m, Set $s, Set ...$others) + public function testMPartialIntersectionIsEmptySetWhenMMoreThanN(int $m, Set $s, Set ...$others) { // Given $emptySet = new Set(); @@ -1347,7 +1347,7 @@ public function testNPartialIntersectionIsEmptySetWhenMMoreThanN(int $m, Set $s, $this->assertEquals($emptySet, $partialIntersection); } - public function dataProviderForNPartialIntersectionIsEmptySetWhenMMoreThanN(): array + public function dataProviderForMPartialIntersectionIsEmptySetWhenMMoreThanN(): array { return [ [