I would like to convert logical relational expressions in disjunctive form, e.g.,
$$(x \lt -1) \lor (-1 \lt x \lt +1) \lor (x \gt +1)$$
into conjunctive form, e.g.,
$$(x \ne -1) \land (x \ne +1)$$
I have some machinery in place that converts a logical relational expressions in disjunctive form into a union of intervals:
ClearAll[mxInterval];
mxInterval::unrecognized = "The expression `` is not an Inequality, Less, LessEqual, GreaterEqual\
or Greater operator or the logical Or of one or more of the operators.";
mxInterval[HoldPattern[Inequality[valueLeft_, ropLeft_, var_, ropRight_, valueRight_]]] :=
mxInterval[ropLeft, valueLeft, valueRight, ropRight];
mxInterval[(rop:(Less|LessEqual))[var_, value_]] :=
mxInterval[LessEqual, "-\[Infinity]", value, rop];
mxInterval[(rop:(Greater|GreaterEqual))[var_, value_]] :=
mxInterval[rop, value, "\[Infinity]", GreaterEqual];
mxInterval[HoldPattern[Or[x__]]] :=
Or @@ Replace[HoldComplete[x], elem_ :> mxInterval[elem], {1}];
mxInterval[expr_] := (Message[mxInterval::unrecognized, expr]; Return $fail;)
mxIntervalSymbol[op_, side_] := Switch[
op,
Less|Greater, Switch[side, l, "[", r, "]"],
LessEqual|GreaterEqual, Switch[side, l, "(", r, ")"]];
mxInterval /: MakeBoxes[mxInterval[ropLeft : (Less|LessEqual|Greater|GreaterEqual),
valueLeft_, valueRight_,
ropRight : (Less|LessEqual|Greater|GreaterEqual)], form_] :=
RowBox[{mxIntervalSymbol[ropLeft, l], MakeBoxes[valueLeft, form], ",",
MakeBoxes[valueRight, form], mxIntervalSymbol[ropRight, r]}];
Using mxInterval on the sample expression produces a disjunction of intervals,
In[]: mxInterval[x < -1 || -1 < x < +1 || x > +1]
Out[]: Or[mxInterval[-\[Infinity],LessEqual,Less,-1],
mxInterval[-1,Less,Less,+1],
mxInterval[+1,Greater,GreaterEqual,\[Infinity]]
which display as:
$$(-\infty, -1] \cup [-1,+1] \cup [+1,+\infty)$$
or, as the number line: oops, which is actually of $(-\infty,-1] \cup [+1,+1\infty)$:

(Note: Maybe I should produce Union instead of Or here. Would that eliminate the needs for a MakeBoxes definition for Or[mxInterval ..]? The only use for that function is to get the $\cup$ operator instead of $\lor$ in the display).
What I would really like is the function mxInterval[Or[mxInterval ..], And] which would take the disjunctive form of intervals and produce the conjunctive form. And, of course, mxInterval[And[mxInterval ..], Or] that would do the reverse.
If I were using a more procedural language, I would sort and then iterate over the intervals constructing the result along the way. However, I feel like the best way to implement the function in Mathematica is to rely heavily on pattern matching, but I'm having trouble formulating a solution using that paradigm.
Or, maybe there is a Mathematica incantation that will do the conversion on the original logical relational expression? That would be sweet.
In[27]:= BooleanConvert[! Reduce[! ee], "CNF"] Out[27]= x != -1 && x != 1– Daniel Lichtblau Mar 9 at 20:06BooleanConvertseems to ignore the form specification for"DNF"and"CNF":BooleanConvert[!Reduce[!result]]produces the same result asBooleanConvert[!Reduce[!result], "DNF"]andBooleanConvert[!Reduce[!result], "CNF"]. Specifying"NAND"and"NOR"does produce the expected results. I'd like to try to understand why this produces the CNF form and add a few more test cases. – RandomBits Mar 9 at 20:35a AND bwith (a,b) both atomic is already in DNF, trivially, as an OR with but one clause. obviously it is also in CNF. This may explain the behavior you note. – Daniel Lichtblau Mar 9 at 20:54