@@ -82,6 +82,33 @@ export const LOGIC_LIBRARY: SymbolDefinitions = {
8282 signature : '(boolean, boolean) -> boolean' ,
8383 evaluate : evaluateImplies ,
8484 } ,
85+ Xor : {
86+ description : 'Exclusive or: true when exactly one operand is true' ,
87+ wikidata : 'Q498186' ,
88+ broadcastable : true ,
89+ commutative : true ,
90+ complexity : 10200 ,
91+ signature : '(boolean, boolean) -> boolean' ,
92+ evaluate : evaluateXor ,
93+ } ,
94+ Nand : {
95+ description : 'Not-and: negation of conjunction' ,
96+ wikidata : 'Q189550' ,
97+ broadcastable : true ,
98+ commutative : true ,
99+ complexity : 10200 ,
100+ signature : '(boolean, boolean) -> boolean' ,
101+ evaluate : evaluateNand ,
102+ } ,
103+ Nor : {
104+ description : 'Not-or: negation of disjunction' ,
105+ wikidata : 'Q189561' ,
106+ broadcastable : true ,
107+ commutative : true ,
108+ complexity : 10200 ,
109+ signature : '(boolean, boolean) -> boolean' ,
110+ evaluate : evaluateNor ,
111+ } ,
85112 // Quantifiers return boolean values (they are propositions)
86113 // They support evaluation over finite domains (e.g., ForAll with Element condition)
87114 // The first argument can be:
@@ -268,6 +295,60 @@ function evaluateImplies(
268295 return undefined ;
269296}
270297
298+ function evaluateXor (
299+ args : ReadonlyArray < BoxedExpression > ,
300+ { engine : ce } : { engine : ComputeEngine }
301+ ) : BoxedExpression | undefined {
302+ const lhs = args [ 0 ] . symbol ;
303+ const rhs = args [ 1 ] . symbol ;
304+ // XOR is true when exactly one operand is true
305+ if (
306+ ( lhs === 'True' && rhs === 'False' ) ||
307+ ( lhs === 'False' && rhs === 'True' )
308+ )
309+ return ce . True ;
310+ if (
311+ ( lhs === 'True' && rhs === 'True' ) ||
312+ ( lhs === 'False' && rhs === 'False' )
313+ )
314+ return ce . False ;
315+ return undefined ;
316+ }
317+
318+ function evaluateNand (
319+ args : ReadonlyArray < BoxedExpression > ,
320+ { engine : ce } : { engine : ComputeEngine }
321+ ) : BoxedExpression | undefined {
322+ // NAND is the negation of AND
323+ const lhs = args [ 0 ] . symbol ;
324+ const rhs = args [ 1 ] . symbol ;
325+ if ( lhs === 'True' && rhs === 'True' ) return ce . False ;
326+ if (
327+ ( lhs === 'True' && rhs === 'False' ) ||
328+ ( lhs === 'False' && rhs === 'True' ) ||
329+ ( lhs === 'False' && rhs === 'False' )
330+ )
331+ return ce . True ;
332+ return undefined ;
333+ }
334+
335+ function evaluateNor (
336+ args : ReadonlyArray < BoxedExpression > ,
337+ { engine : ce } : { engine : ComputeEngine }
338+ ) : BoxedExpression | undefined {
339+ // NOR is the negation of OR
340+ const lhs = args [ 0 ] . symbol ;
341+ const rhs = args [ 1 ] . symbol ;
342+ if ( lhs === 'False' && rhs === 'False' ) return ce . True ;
343+ if (
344+ ( lhs === 'True' && rhs === 'True' ) ||
345+ ( lhs === 'True' && rhs === 'False' ) ||
346+ ( lhs === 'False' && rhs === 'True' )
347+ )
348+ return ce . False ;
349+ return undefined ;
350+ }
351+
271352export function simplifyLogicFunction (
272353 x : BoxedExpression
273354) : { value : BoxedExpression ; because : string } | undefined {
@@ -277,6 +358,9 @@ export function simplifyLogicFunction(
277358 Not : evaluateNot ,
278359 Equivalent : evaluateEquivalent ,
279360 Implies : evaluateImplies ,
361+ Xor : evaluateXor ,
362+ Nand : evaluateNand ,
363+ Nor : evaluateNor ,
280364 } [ x . operator ] ;
281365
282366 if ( ! fn || ! x . ops ) return undefined ;
0 commit comments