3939final class TrinaryLogic
4040{
4141
42- private const YES = 1 ;
43- private const MAYBE = 0 ;
44- private const NO = - 1 ;
42+ private const YES = 3 ;
43+ private const MAYBE = 1 ;
44+ private const NO = 0 ;
4545
4646 /** @var self[] */
4747 private static array $ registry = [];
4848
49+ private static self $ YES ;
50+
51+ private static self $ MAYBE ;
52+
53+ private static self $ NO ;
54+
4955 private function __construct (private int $ value )
5056 {
5157 }
5258
5359 public static function createYes (): self
5460 {
55- return self ::$ registry [self ::YES ] ??= new self (self ::YES );
61+ return self ::$ YES ??= ( self :: $ registry [self ::YES ] ??= new self (self ::YES ) );
5662 }
5763
5864 public static function createNo (): self
5965 {
60- return self ::$ registry [self ::NO ] ??= new self (self ::NO );
66+ return self ::$ NO ??= ( self :: $ registry [self ::NO ] ??= new self (self ::NO ) );
6167 }
6268
6369 public static function createMaybe (): self
6470 {
65- return self ::$ registry [self ::MAYBE ] ??= new self (self ::MAYBE );
71+ return self ::$ MAYBE ??= ( self :: $ registry [self ::MAYBE ] ??= new self (self ::MAYBE ) );
6672 }
6773
6874 public static function createFromBoolean (bool $ value ): self
@@ -73,8 +79,7 @@ public static function createFromBoolean(bool $value): self
7379
7480 private static function create (int $ value ): self
7581 {
76- self ::$ registry [$ value ] ??= new self ($ value );
77- return self ::$ registry [$ value ];
82+ return self ::$ registry [$ value ] ??= new self ($ value );
7883 }
7984
8085 /**
@@ -113,17 +118,13 @@ public function toBooleanType(): BooleanType
113118 return new ConstantBooleanType ($ this ->value === self ::YES );
114119 }
115120
116- public function and (self ...$ operands ): self
121+ public function and (? self $ operand = null , self ...$ rest ): self
117122 {
118- $ min = $ this ->value ;
119- foreach ($ operands as $ operand ) {
120- if ($ operand ->value >= $ min ) {
121- continue ;
122- }
123-
124- $ min = $ operand ->value ;
123+ $ min = $ this ->value & ($ operand !== null ? $ operand ->value : self ::YES );
124+ foreach ($ rest as $ restOperand ) {
125+ $ min &= $ restOperand ->value ;
125126 }
126- return self ::create ($ min );
127+ return self ::$ registry [ $ min ] ??= new self ($ min );
127128 }
128129
129130 /**
@@ -153,17 +154,13 @@ public function lazyAnd(
153154 return $ this ->and (...$ results );
154155 }
155156
156- public function or (self ...$ operands ): self
157+ public function or (? self $ operand = null , self ...$ rest ): self
157158 {
158- $ max = $ this ->value ;
159- foreach ($ operands as $ operand ) {
160- if ($ operand ->value < $ max ) {
161- continue ;
162- }
163-
164- $ max = $ operand ->value ;
159+ $ max = $ this ->value | ($ operand !== null ? $ operand ->value : self ::NO );
160+ foreach ($ rest as $ restOperand ) {
161+ $ max |= $ restOperand ->value ;
165162 }
166- return self ::create ($ max );
163+ return self ::$ registry [ $ max ] ??= new self ($ max );
167164 }
168165
169166 /**
@@ -247,7 +244,7 @@ public static function maxMin(self ...$operands): self
247244 throw new ShouldNotHappenException ();
248245 }
249246 $ operandValues = array_column ($ operands , 'value ' );
250- return self ::create (max ($ operandValues ) > 0 ? 1 : min ($ operandValues ));
247+ return self ::create (max ($ operandValues ) > self :: MAYBE ? self :: YES : min ($ operandValues ));
251248 }
252249
253250 /**
@@ -275,7 +272,10 @@ public static function lazyMaxMin(
275272
276273 public function negate (): self
277274 {
278- return self ::create (-$ this ->value );
275+ // 0b11 >> 0 == 0b11 (3)
276+ // 0b11 >> 1 == 0b01 (1)
277+ // 0b11 >> 3 == 0b00 (0)
278+ return self ::create (3 >> $ this ->value );
279279 }
280280
281281 public function equals (self $ other ): bool
0 commit comments