3838 */
3939final class TrinaryLogic
4040{
41+ private const YES = 3 ;
42+ private const MAYBE = 1 ;
43+ private const NO = 0 ;
4144
42- private const YES = 1 ;
43- private const MAYBE = 0 ;
44- private const NO = -1 ;
4545
4646 /** @var self[] */
4747 private static array $ registry = [];
4848
49+ private static self $ YES ;
50+ private static self $ MAYBE ;
51+ private static self $ NO ;
52+
4953 private function __construct (private int $ value )
5054 {
5155 }
5256
5357 public static function createYes (): self
5458 {
55- return self ::$ registry [self ::YES ] ??= new self (self ::YES );
59+ return self ::$ YES ??= ( self :: $ registry [self ::YES ] ??= new self (self ::YES ) );
5660 }
5761
5862 public static function createNo (): self
5963 {
60- return self ::$ registry [self ::NO ] ??= new self (self ::NO );
64+ return self ::$ NO ??= ( self :: $ registry [self ::NO ] ??= new self (self ::NO ) );
6165 }
6266
6367 public static function createMaybe (): self
6468 {
65- return self ::$ registry [self ::MAYBE ] ??= new self (self ::MAYBE );
69+ return self ::$ MAYBE ??= ( self :: $ registry [self ::MAYBE ] ??= new self (self ::MAYBE ) );
6670 }
6771
6872 public static function createFromBoolean (bool $ value ): self
@@ -73,8 +77,7 @@ public static function createFromBoolean(bool $value): self
7377
7478 private static function create (int $ value ): self
7579 {
76- self ::$ registry [$ value ] ??= new self ($ value );
77- return self ::$ registry [$ value ];
80+ return self ::$ registry [$ value ] ??= new self ($ value );
7881 }
7982
8083 /**
@@ -113,17 +116,13 @@ public function toBooleanType(): BooleanType
113116 return new ConstantBooleanType ($ this ->value === self ::YES );
114117 }
115118
116- public function and (self ...$ operands ): self
119+ public function and (? self $ operand = null , self ...$ rest ): self
117120 {
118- $ min = $ this ->value ;
119- foreach ($ operands as $ operand ) {
120- if ($ operand ->value >= $ min ) {
121- continue ;
122- }
123-
124- $ min = $ operand ->value ;
121+ $ min = $ this ->value & ($ operand !== null ? $ operand ->value : self ::YES );
122+ foreach ($ rest as $ operand ) {
123+ $ min &= $ operand ->value ;
125124 }
126- return self ::create ($ min );
125+ return self ::$ registry [ $ min ] ??= new self ($ min );
127126 }
128127
129128 /**
@@ -153,17 +152,13 @@ public function lazyAnd(
153152 return $ this ->and (...$ results );
154153 }
155154
156- public function or (self ...$ operands ): self
155+ public function or (? self $ operand = null , self ...$ rest ): self
157156 {
158- $ max = $ this ->value ;
159- foreach ($ operands as $ operand ) {
160- if ($ operand ->value < $ max ) {
161- continue ;
162- }
163-
164- $ max = $ operand ->value ;
157+ $ max = $ this ->value | ($ operand !== null ? $ operand ->value : self ::NO );
158+ foreach ($ rest as $ operand ) {
159+ $ max |= $ operand ->value ;
165160 }
166- return self ::create ($ max );
161+ return self ::$ registry [ $ max ] ??= new self ($ max );
167162 }
168163
169164 /**
@@ -247,7 +242,7 @@ public static function maxMin(self ...$operands): self
247242 throw new ShouldNotHappenException ();
248243 }
249244 $ operandValues = array_column ($ operands , 'value ' );
250- return self ::create (max ($ operandValues ) > 0 ? 1 : min ($ operandValues ));
245+ return self ::create (max ($ operandValues ) > self :: MAYBE ? self :: YES : min ($ operandValues ));
251246 }
252247
253248 /**
@@ -275,7 +270,10 @@ public static function lazyMaxMin(
275270
276271 public function negate (): self
277272 {
278- return self ::create (-$ this ->value );
273+ // 0b11 >> 0 == 0b11 (3)
274+ // 0b11 >> 1 == 0b01 (1)
275+ // 0b11 >> 3 == 0b00 (0)
276+ return self ::create (3 >> $ this ->value );
279277 }
280278
281279 public function equals (self $ other ): bool
0 commit comments