Function Repository Resource:

BooleanCompose

Source Notebook

Functionally compose a Boolean expression

Contributed by: Jesse Friedman

ResourceFunction["BooleanCompose"][expr]

represents a composition of the variables in the Boolean expression expr, where each variable is a function.

Details and Options

ResourceFunction["BooleanCompose"] allows you to “pre-compose” logic which can later be applied to a value.
Each of the Boolean variables in expr is treated as a function and is applied to the argument or arguments the composition as a whole is applied to, after which the results are substituted in place of their corresponding variables and the Boolean expression is evaluated.
The expression expr can involve any combination of Boolean functions supported by BooleanVariables, such as And, Or, Not, and arbitrary BooleanFunction objects.

Examples

Basic Examples (1) 

Create a predicate that returns True if its argument is both positive and an even number:

In[1]:=
positiveAndEvenQ = ResourceFunction["BooleanCompose"][Positive && EvenQ]
Out[1]=
In[2]:=
positiveAndEvenQ[4]
Out[2]=
In[3]:=
positiveAndEvenQ[5]
Out[3]=
In[4]:=
positiveAndEvenQ[-4]
Out[4]=

Scope (6) 

Pure functions can be used in the composition:

In[5]:=
oddAndLessThanFiveQ = ResourceFunction["BooleanCompose"][OddQ && (# < 5 &)]
Out[5]=
In[6]:=
oddAndLessThanFiveQ /@ {1, 3, 5, 7}
Out[6]=

The composition can be applied to multiple arguments:

In[7]:=
firstGTSecondOrDifferenceGTTenQ = ResourceFunction[
  "BooleanCompose"][(#1 > #2 &) || (Abs[#1 - #2] > 10 &)]
Out[7]=
In[8]:=
firstGTSecondOrDifferenceGTTenQ[5, 3]
Out[8]=
In[9]:=
firstGTSecondOrDifferenceGTTenQ[2, 6]
Out[9]=
In[10]:=
firstGTSecondOrDifferenceGTTenQ[2, 23]
Out[10]=

Multiple identical Boolean variables are only applied once each:

In[11]:=
myFunctionWithSideEffect = (x++; True) &;
In[12]:=
x = 0;
ResourceFunction["BooleanCompose"][
  myFunctionWithSideEffect && myFunctionWithSideEffect][4]
Out[13]=
In[14]:=
x
Out[14]=

If any of the Boolean variables are not functions, applying the composition may yield a symbolic result:

In[15]:=
ResourceFunction["BooleanCompose"][(y || z) && OddQ][3]
Out[15]=

However, if the Boolean expression can be short-circuited, a Boolean value will be returned:

In[16]:=
ResourceFunction["BooleanCompose"][(y || z) && OddQ][2]
Out[16]=

All of the basic Boolean operators are supported:

In[17]:=
AssociationMap[
 Function[operator, ResourceFunction["BooleanCompose"][
   operator[OddQ, LessThan[5]]]], {And, Or, Nand, Nor, Xor, Xnor}]
Out[17]=
In[18]:=
#[3] & /@ %
Out[18]=

BooleanFunction is supported:

In[19]:=
f = ResourceFunction["BooleanCompose"]@
  BooleanFunction[30, {GreaterThan[3], LessThan[20], EvenQ}]
Out[19]=
In[20]:=
GroupBy[Range[25], f]
Out[20]=

Applications (2) 

Improve code readability by using functional-style composition:

In[21]:=
testValues = {
   {},
   {1},
   {1, 2},
   {1, 2, 3},
   $Failed
   };
In[22]:=
ResourceFunction["BooleanCompose"][
  (ListQ && Length/*GreaterThan[1]) || FailureQ
  ] /@ testValues
Out[22]=

Compare to a more conventional pure function-based approach:

In[23]:=
(ListQ[#] && Length[#] > 1) || FailureQ[#] & /@ testValues
Out[23]=

While slightly more verbose, some may prefer the literacy and reduced duplication of the compositional style.

Possible Issues (2) 

Every unique function in the Boolean expression will be applied to the argument(s) that the composition is applied to, even if the expression can be short-circuited:

In[24]:=
myFunctionWithSideEffect = (x++; True) &;
In[25]:=
x = 0;
ResourceFunction["BooleanCompose"][
  OddQ && myFunctionWithSideEffect][4]
Out[26]=
In[27]:=
x
Out[27]=

The exception to this is the case where the expression is automatically simplified by the parser due to presence of a raw Boolean value:

In[28]:=
x = 0;
ResourceFunction["BooleanCompose"][
  False && myFunctionWithSideEffect][4]
Out[29]=
In[30]:=
x
Out[30]=

Publisher

Jesse Friedman

Version History

  • 2.0.0 – 29 April 2020
  • 1.0.0 – 22 October 2019

License Information