1414 */
1515final class TrinaryLogic
1616{
17+ private const YES = 3 ;
18+ private const MAYBE = 1 ;
19+ private const NO = 0 ;
1720
18- private const YES = 1 ;
19- private const MAYBE = 0 ;
20- private const NO = -1 ;
2121
2222 /** @var self[] */
2323 private static array $ registry = [];
2424
25+ private static self $ YES ;
26+ private static self $ MAYBE ;
27+ private static self $ NO ;
28+
2529 private function __construct (private int $ value )
2630 {
2731 }
2832
2933 public static function createYes (): self
3034 {
31- return self ::$ registry [self ::YES ] ??= new self (self ::YES );
35+ return self ::$ YES ??= ( self :: $ registry [self ::YES ] ??= new self (self ::YES ) );
3236 }
3337
3438 public static function createNo (): self
3539 {
36- return self ::$ registry [self ::NO ] ??= new self (self ::NO );
40+ return self ::$ NO ??= ( self :: $ registry [self ::NO ] ??= new self (self ::NO ) );
3741 }
3842
3943 public static function createMaybe (): self
4044 {
41- return self ::$ registry [self ::MAYBE ] ??= new self (self ::MAYBE );
45+ return self ::$ MAYBE ??= ( self :: $ registry [self ::MAYBE ] ??= new self (self ::MAYBE ) );
4246 }
4347
4448 public static function createFromBoolean (bool $ value ): self
@@ -49,8 +53,7 @@ public static function createFromBoolean(bool $value): self
4953
5054 private static function create (int $ value ): self
5155 {
52- self ::$ registry [$ value ] ??= new self ($ value );
53- return self ::$ registry [$ value ];
56+ return self ::$ registry [$ value ] ??= new self ($ value );
5457 }
5558
5659 /**
@@ -89,17 +92,13 @@ public function toBooleanType(): BooleanType
8992 return new ConstantBooleanType ($ this ->value === self ::YES );
9093 }
9194
92- public function and (self ...$ operands ): self
95+ public function and (self $ operand , self ...$ rest ): self
9396 {
94- $ min = $ this ->value ;
95- foreach ($ operands as $ operand ) {
96- if ($ operand ->value >= $ min ) {
97- continue ;
98- }
99-
100- $ min = $ operand ->value ;
97+ $ min = $ this ->value & $ operand ->value ;
98+ foreach ($ rest as $ operand ) {
99+ $ min &= $ operand ->value ;
101100 }
102- return self ::create ($ min );
101+ return self ::$ registry [ $ min ] ??= new self ($ min );
103102 }
104103
105104 /**
@@ -129,17 +128,13 @@ public function lazyAnd(
129128 return $ this ->and (...$ results );
130129 }
131130
132- public function or (self ...$ operands ): self
131+ public function or (self $ operand , self ...$ rest ): self
133132 {
134- $ max = $ this ->value ;
135- foreach ($ operands as $ operand ) {
136- if ($ operand ->value < $ max ) {
137- continue ;
138- }
139-
140- $ max = $ operand ->value ;
133+ $ max = $ this ->value | $ operand ->value ;
134+ foreach ($ rest as $ operand ) {
135+ $ max |= $ operand ->value ;
141136 }
142- return self ::create ($ max );
137+ return self ::$ registry [ $ max ] ??= new self ($ max );
143138 }
144139
145140 /**
@@ -217,7 +212,7 @@ public static function maxMin(self ...$operands): self
217212 throw new ShouldNotHappenException ();
218213 }
219214 $ operandValues = array_column ($ operands , 'value ' );
220- return self ::create (max ($ operandValues ) > 0 ? 1 : min ($ operandValues ));
215+ return self ::create (max ($ operandValues ) > self :: MAYBE ? self :: YES : min ($ operandValues ));
221216 }
222217
223218 /**
@@ -245,7 +240,10 @@ public static function lazyMaxMin(
245240
246241 public function negate (): self
247242 {
248- return self ::create (-$ this ->value );
243+ // 0b11 >> 0 == 0b11 (3)
244+ // 0b11 >> 1 == 0b01 (1)
245+ // 0b11 >> 3 == 0b00 (0)
246+ return self ::create (3 >> $ this ->value );
249247 }
250248
251249 public function equals (self $ other ): bool
0 commit comments