Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 26 additions & 28 deletions src/TrinaryLogic.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,35 @@
*/
final class TrinaryLogic
{
private const YES = 3;
private const MAYBE = 1;
private const NO = 0;

private const YES = 1;
private const MAYBE = 0;
private const NO = -1;

/** @var self[] */
private static array $registry = [];

private static self $YES;
private static self $MAYBE;
private static self $NO;

private function __construct(private int $value)
{
}

public static function createYes(): self
{
return self::$registry[self::YES] ??= new self(self::YES);
return self::$YES ??= (self::$registry[self::YES] ??= new self(self::YES));
}

public static function createNo(): self
{
return self::$registry[self::NO] ??= new self(self::NO);
return self::$NO ??= (self::$registry[self::NO] ??= new self(self::NO));
}

public static function createMaybe(): self
{
return self::$registry[self::MAYBE] ??= new self(self::MAYBE);
return self::$MAYBE ??= (self::$registry[self::MAYBE] ??= new self(self::MAYBE));
}

public static function createFromBoolean(bool $value): self
Expand All @@ -49,8 +53,7 @@

private static function create(int $value): self
{
self::$registry[$value] ??= new self($value);
return self::$registry[$value];
return self::$registry[$value] ??= new self($value);
}

/**
Expand Down Expand Up @@ -89,17 +92,13 @@
return new ConstantBooleanType($this->value === self::YES);
}

public function and(self ...$operands): self
public function and(?self $operand = null, self ...$rest): self
{
$min = $this->value;
foreach ($operands as $operand) {
if ($operand->value >= $min) {
continue;
}

$min = $operand->value;
$min = $this->value & ($operand !== null ? $operand->value : self::YES);
foreach ($rest as $operand) {

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.3)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.5)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Foreach overwrites $operan

Check failure on line 98 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Foreach overwrites $operan
$min &= $operand->value;
}
return self::create($min);
return self::$registry[$min] ??= new self($min);
}

/**
Expand Down Expand Up @@ -129,17 +128,13 @@
return $this->and(...$results);
}

public function or(self ...$operands): self
public function or(?self $operand = null, self ...$rest): self
{
$max = $this->value;
foreach ($operands as $operand) {
if ($operand->value < $max) {
continue;
}

$max = $operand->value;
$max = $this->value | ($operand !== null ? $operand->value : self::NO);
foreach ($rest as $operand) {

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.3)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.5)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, ubuntu-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, windows-latest)

Foreach overwrites $operand with its value variable.

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.3, ubuntu-latest)

Foreach overwrites $opera

Check failure on line 134 in src/TrinaryLogic.php

View workflow job for this annotation

GitHub Actions / Mutation Testing (8.4, ubuntu-latest)

Foreach overwrites $opera
$max |= $operand->value;
}
return self::create($max);
return self::$registry[$max] ??= new self($max);
}

/**
Expand Down Expand Up @@ -217,7 +212,7 @@
throw new ShouldNotHappenException();
}
$operandValues = array_column($operands, 'value');
return self::create(max($operandValues) > 0 ? 1 : min($operandValues));
return self::create(max($operandValues) > self::MAYBE ? self::YES : min($operandValues));
}

/**
Expand Down Expand Up @@ -245,7 +240,10 @@

public function negate(): self
{
return self::create(-$this->value);
// 0b11 >> 0 == 0b11 (3)
// 0b11 >> 1 == 0b01 (1)
// 0b11 >> 3 == 0b00 (0)
return self::create(3 >> $this->value);
}

public function equals(self $other): bool
Expand Down
Loading