Skip to content

sxpr.py

sxpr.py

Functions for working with s-expressions.

s-expressions are inspired from ELisp.

SatSxpr

Bases: Sxpr[Src, bool]

A subclass of Sxpr[--, bool].

Parameters:

Name Type Description Default
op

obj:Callable[[bool, Src], bool]): This can only be one of two options -- either sat_and or sat_or.

required
terms

obj:Tuple[Src, ...]): a tuple of terms.

required

Returns:

Type Description

Computes init value based on op. Then calls the __init__ method of Sxpr.

Source code in normal_form/sxpr.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class SatSxpr(Sxpr[Src, bool]):  # pylint: disable=too-few-public-methods
    """A subclass of Sxpr[--, bool].

    Args:
       op (:obj:`Callable[[bool, Src], bool]`): This can only be one of two options --
          either `sat_and` or `sat_or`.
       terms (:obj:`Tuple[Src, ...]`): a tuple of terms.

    Returns:
       Computes `init` value based on `op`. Then calls the `__init__` method of `Sxpr`.
    """
    def __init__(self, op: Callable[[bool, Src], bool], terms: Tuple[Src, ...]):
        init: bool
        if op.__name__ in ('sat_and', 'and_'):
            init = True
        elif op.__name__ in ('sat_or', 'or_'):
            init = False
        else:
            raise ValueError(f'Unknown operation {op.__name__ = } encountered')
        super().__init__(op, terms, init)

    def __repr__(self) -> str:  # pragma: no cover
        """Use for pretty-printing an S-expression."""
        if self.op.__name__ in ('sat_and', 'and'):
            symb: str = ' ∧ '
            color: str = Fore.RED
        elif self.op.__name__ in ('sat_or', 'or'):
            symb = ' ∨ '
            color = Fore.GREEN
        else:
            symb = ' ? '
            color = ''
            logger.warning(f'Unknown operation {self.op.__name__ = } encountered')

        reset: str = Style.RESET_ALL
        colored_symbol: str = color + symb + reset
        bracket: Tuple[str, str] = (color + "[" + reset, color + "]" + reset)

        if not self.terms:
            return bracket[0] + colored_symbol.join(map(repr, [self.init])) + bracket[1]
        return bracket[0] + colored_symbol.join(map(repr, self.terms)) + bracket[1]

__repr__()

Use for pretty-printing an S-expression.

Source code in normal_form/sxpr.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
def __repr__(self) -> str:  # pragma: no cover
    """Use for pretty-printing an S-expression."""
    if self.op.__name__ in ('sat_and', 'and'):
        symb: str = ' ∧ '
        color: str = Fore.RED
    elif self.op.__name__ in ('sat_or', 'or'):
        symb = ' ∨ '
        color = Fore.GREEN
    else:
        symb = ' ? '
        color = ''
        logger.warning(f'Unknown operation {self.op.__name__ = } encountered')

    reset: str = Style.RESET_ALL
    colored_symbol: str = color + symb + reset
    bracket: Tuple[str, str] = (color + "[" + reset, color + "]" + reset)

    if not self.terms:
        return bracket[0] + colored_symbol.join(map(repr, [self.init])) + bracket[1]
    return bracket[0] + colored_symbol.join(map(repr, self.terms)) + bracket[1]

Sxpr dataclass

Bases: Generic[Src, Trgt]

Define generic S-expression.

Source code in normal_form/sxpr.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@dataclass
class Sxpr(Generic[Src, Trgt]):
    """Define generic S-expression."""

    op: Callable[[Trgt, Src], Trgt]  # pylint: disable=invalid-name
    terms: Tuple[Src, ...]
    init: Trgt

    def reduce(self) -> Trgt:
        """Use ft.reduce to evaluate the s-expression.

        Example:
           (+, (1 2 3 4), 0) will evaluate to ((((0 + 1) + 2) + 3) + 4).
        """
        return ft.reduce(self.op, self.terms, self.init)

reduce()

Use ft.reduce to evaluate the s-expression.

Example

(+, (1 2 3 4), 0) will evaluate to ((((0 + 1) + 2) + 3) + 4).

Source code in normal_form/sxpr.py
28
29
30
31
32
33
34
def reduce(self) -> Trgt:
    """Use ft.reduce to evaluate the s-expression.

    Example:
       (+, (1 2 3 4), 0) will evaluate to ((((0 + 1) + 2) + 3) + 4).
    """
    return ft.reduce(self.op, self.terms, self.init)

Last update: September 11, 2022