Logical functions and gate builders

module: rspub.util.gates

Logical functions, gate and gate builders

Logical functions

Each logical function takes a one-argument predicate or a list of one-argument predicates. In turn each logical function returns a one-argument predicate that is the chain of, or the negation of its arguments. There are functions to chain predicates along not_(), and_(), or_(), nand_(), nor_(), xor_() and xnor_().

Each logical function, before returning the chained predicate, will check if the predicates in the argument list are truly one-argument predicates. The behavior after detection of a wrong argument can be set by the module-method set_stop_on_creation_error(). The default behavior after detection of a wrong argument is to throw a GateCreationException.

Example usage

Given closures or lambda’s:

>>> spam = lambda word : word.startswith("spam")
>>> eggs = lambda word: word.endswith("eggs")
>>> ampersand = lambda word: len(word.split("&")) > 1

Now you can create a test for spam & eggs:

>>> from rspub.util.gates import and_
>>> spam_and_eggs = and_(spam, eggs, ampersand)

and reuse spam and eggs to create spam nor eggs:

>>> from rspub.util.gates import nor_
>>> spam_nor_eggs = nor_(spam, eggs)

and use the assembled predicates:

>>> spam_and_eggs("spam & eggs")
True
>>> spam_and_eggs("spamming leggs")
False
>>> spam_nor_eggs("bacon")
True

Of course your closures and lambda’s all need to be able to handle the type of argument given.

Gate

The function gate() takes two lists of predicates, includes and excludes. Includes is the list of predicates that can permit x through the gate; excludes is the list of predicates that can prevent x from passing the gate.

Building gates

The abstract class GateBuilder defines the methods to construct a GateBuilder. The concrete class PluggedInGateBuilder walks zero or more plugin directories looking for specifically named builders in order to build a customized gate().

If GateBuilder s are chained, a builder can overrule includes and excludes from previous builders.


Classes and functions

rspub.util.gates.not_(predicate)[source]

Creates the negation of the given predicate

The outcome of a not_ f for any x is:

f(x) = not p(x)

where p is the given predicate.

Parameters:predicate – the predicate to negate
Returns:a new predicate implementing the negation of the given predicate
rspub.util.gates.and_(*predicates)[source]

Creates the logical conjunction of the given predicates

Chains predicates in and. The outcome of an and_ f for any x is:

f(x) = p_1(x) and p_2(x) and ... and p_n(x)

where p_1 ... p_n are the given predicates.

The chain of predicates is True if all predicates are True, otherwise False. Outcome True in effect says that all of the predicates evaluated as True.

Logical performance has been optimized. i.e. A and B and C is False if A evaluates as False; do not test B and C in this case.

Parameters:predicates – predicates to chain in and.
Returns:a new predicate implementing the combined and of the given predicates
rspub.util.gates.nor_(*predicates)[source]

Creates the joint denial of the given predicates

Chains predicates in nor. The outcome of a nor_ f for any x is:

f(x) = not(p_1(x) or p_2(x) or ... or p_n(x))

where p_1 ... p_n are the given predicates.

The chain of predicates is False if at least one predicate is True, otherwise True. Outcome True in effect says that neither one of the predicates evaluated as True.

Logical performance has been optimized. i.e. A nor B nor C is False if A evaluates as True; do not test B and C in this case.

Parameters:predicates – predicates to chain in nor.
Returns:a new predicate implementing the combined nor of the given predicates
rspub.util.gates.or_(*predicates)[source]

Creates the logical inclusive disjunction of the given predicates

Chains predicates in or. The outcome of an or_ f for any x is:

f(x) = p_1(x) or p_2(x) or ... or p_n(x)

where p_1 ... p_n are the given predicates.

The chain of predicates is True if at least one predicate is True, otherwise False. Outcome True in effect says that at least one of the predicates evaluated as True.

Logical performance has been optimized. i.e. A or B or C is True if A evaluates as True; do not test B and C in this case.

Parameters:predicates – predicates to chain in or.
Returns:a new predicate implementing the combined or of the given predicates
rspub.util.gates.nand_(*predicates)[source]

Creates the alternative denial of the given predicates

Chains predicates in nand. The outcome of a nand_ f for any x is:

f(x) = not(p_1(x) and p_2(x) and ... and p_n(x))

where p_1 ... p_n are the given predicates.

The chain of predicates is False if all predicates are True, otherwise True. Outcome True in effect says that at least one of the predicates evaluated as False.

Logical performance has been optimized. i.e. A nand B nand C is True if A evaluates as False; do not test B and C in this case.

Parameters:predicates – predicates to chain in nand.
Returns:a new predicate implementing the combined nand of the given predicates
rspub.util.gates.xor_(*predicates)[source]

Creates the exclusive disjunction of the given predicates

Chains predicates in xor. The outcome of an xor_ f for any x is:

f(x) = p_1(x) xor p_2(x) xor ... xor p_n(x)

where p_1 ... p_n are the given predicates.

One definition of xor says: “A chain of XORs—a XOR b XOR c XOR d (and so on)—is true whenever an odd number of the inputs are true and is false whenever an even number of inputs are true. https://en.wikipedia.org/wiki/Exclusive_or

Some definitions even deny that there can be more than two inputs: “a Boolean operator working on two variables that has the value one if one but not both of the variables is one”. https://www.google.nl/search?q=define+exclusive+OR

However, this implementation adheres to:

The chain of predicates is True if one and only one predicate is True, otherwise False.

Parameters:predicates – predicates to chain with xor.
Returns:a new predicate implementing the combined xor of the given predicates
rspub.util.gates.xnor_(*predicates)[source]

Creates the logical equality of the given predicates

Chains predicates in xnor. The outcome of an xnor_ f for any x is:

f(x) = (p_1(x) and p_2(x) and ... and p_n(x)) or not(p_1(x) or p_2(x) or ... or p_n(x))

where p_1 ... p_n are the given predicates.

The chain of predicates is True if all predicates evaluate as True or all predicates evaluate as False. (So this is not the negation of xor as implemented above.)

Parameters:predicates – predicates to chain with xnor.
Returns:a new predicate implementing the combined xnor of the given predicates
rspub.util.gates.gate(includes=[], excludes=[])[source]

Creates the logical conjunction of or_(includes), nor_(excludes)

Chains including predicates and excluding predicates. The outcome of a gate g for any x is:

g(x) = (i_1(x) or i_2(x) or ... or i_n(x)) and not(e_1(x) or e_2(x) or ... or e_n(x))

where i_1 ... i_n are given including predicates and e_1 ... e_n are given excluding predicates.

The gate evaluates as True if at least one of includes is True and none of excludes are True.

Parameters:
  • includes (list) – predicates that permit x through gate
  • excludes (list) – predicates that restrict x from gate
Returns:

a new predicate implementing the combined functions given in includes and excludes

class rspub.util.gates.GateBuilder[source]

Bases: object

Abstract builder class for gates

GateBuilders should extend this abstract class or implement the next two methods. In these methods GateBuilders are free to extend on previously defined lists of permitting and restricting predicates, remove elements from them or overrule previous steps and return complete new lists.

See also

gate()

build_includes(includes: list) → list[source]

Define the list of permitting predicates

Either rework the given list (append, extend, remove, replace), return the given list or return a complete new list. The returned list should consist of one-argument predicates.

Parameters:includes (list) – the list of permitting predicates (from previous builders)
Returns:the list of permitting predicates as defined by this GateBuilder
build_excludes(excludes: list) → list[source]

Define the list of restricting predicates

Either rework the given list (append, extend, remove, replace), return the given list or return a complete new list. The returned list should consist of one-argument predicates.

Parameters:excludes (list) – the list of restricting predicates (from previous builders)
Returns:the list of restricting predicates as defined by this GateBuilder
class rspub.util.gates.PluggedInGateBuilder(builder_name: str, first_builder: rspub.util.gates.GateBuilder = None, *plugin_directories: str)[source]

Bases: rspub.util.gates.GateBuilder

Builds pluggable gates

The PluggedInGateBuilder can be given zero or more directories where it will recursively look for GateBuilders of the given builder_name. It will then instantiate the builder and give it the opportunity to determine the list of including predicates and the list of excluding predicates as this builder calls build_includes() and build_excludes() on the plugged-in builder.

A class in the given plugin_directories will qualify as builder if at least

  • it has a name equal to the given builder_name and
  • it is a subclass of GateBuilder or it implements both methods of this class.

The final gate() can be obtained by calling build_gate().

__init__(builder_name: str, first_builder: rspub.util.gates.GateBuilder = None, *plugin_directories: str)[source]

Initialize a PluggedInGateBuilder

Parameters:
  • builder_name (str) – the class name (either simple or qualified) of the class implementing the GateBuilder methods.
  • first_builder (GateBuilder) – builder of default or initial predicates, may be None
  • plugin_directories (str) – the directories where to search for GateBuilders with the given builder_name
build_includes(includes=[]) → list[source]

Set initial permitting predicates

Parameters:includes (list) – the list of initial permitting predicates
Returns:the list of initial permitting predicates
Raises:GateCreationException if a predicate was not a one-argument predicate
build_excludes(excludes=[]) → list[source]

Set initial restricting predicates

Parameters:excludes (list) – the list of initial restricting predicates
Returns:the list of initial restricting predicates
Raises:GateCreationException if a predicate was not a one-argument predicate
build_gate() → <function gate at 0x7fbf0cffac80>[source]

Build a gate as defined by found GateBuilders in plugin_directories

Found GateBuilders are given the chance to modify the lists includes and excludes. The initial lists includes and excludes are populated by predicates as defined by first_builder. If no first_builder was given, the initial lists will be empty lists.

Returns:gate() as defined by found GateBuilders.
Raises:GateCreationException if a gate could not be created because a given value is not a one-argument predicate.
Raises:GateBuilderException if a gate could not be built because of inappropriate behavior of a GateBuilder.
exception rspub.util.gates.GateCreationException[source]

Bases: ValueError

Indicates a gate could not be created because a given value is not a one-argument predicate

exception rspub.util.gates.GateBuilderException[source]

Bases: rspub.util.gates.GateCreationException

Indicates a gate could not be built because of inappropriate behavior of a GateBuilder

rspub.util.gates.set_stop_on_creation_error(stop)[source]

Determine module-wide behavior on gate creation errors

The function is_one_arg_predicate() will be called throughout this module by logical functions and gate builder classes in order to detect if a given value is a one-argument predicate. What the behavior of the detecting function will be after detecting a wrong input value can be determined by this method. Either an error message will be logged (stop = False) or a GateCreationException will be raised (stop = True).

Parameters:stop (boolean) – True for stop on creation error, False otherwise
Returns:the previous state
rspub.util.gates.stop_on_creation_error()[source]

Module-wide behavior on gate creation errors

Returns:True if stops on creation error, False otherwise
rspub.util.gates.is_one_arg_predicate(p)[source]

Determines if the given p is a one-argument predicate

Parameters:p – value to be inspected
Returns:True if p is a one-argument predicate, False otherwise
Raises:GateCreationException if p is not a one-argument predicate and stop_on_creation_error() is True