.. _multi algebras page: ============== Multi-algebras ============== Let :math:`\Sigma` be a propositional signature. A *multi-algebra* over :math:`\Sigma` is a structure :math:`\mathbf{V} = \langle V, \cdot^{\mathbf{V}} \rangle`, where :math:`V` is a non-empty collection, called the *carrier* of :math:`\mathbf{V}` and, for each connective :math:`\# \in \Sigma_k`, the mapping :math:`\#^\mathbf{V}:V^k \to \mathsf{Power}(V)` is the interpretation of :math:`\#` in :math:`\mathbf{V}`. In *ct4l*, we build a finite multi-algebra over a :cpp:class:`ct4l::PropSignature` by constructing an object of the class :cpp:class:`ct4l::MultiAlgebra` using a :cpp:class:`ct4l::Domain` object to represent :math:`V` and :cpp:class:`ct4l::TruthTableI` objects to provide the interpretations. Let us build an example, to be used in the remainder of this document. .. _boolean algebra example: Example: Building the two-element Boolean algebra ------------------------------------------------- Let us build the algebra :math:`\mathbf{B}` over the signature :math:`\Sigma` such that - :math:`\Sigma_0 = \{\mathsf{top}, \mathsf{bot}\}` - :math:`\Sigma_1 = \{\mathsf{not}\}` - :math:`\Sigma_2 = \{\mathsf{and}, \mathsf{or}\}` - :math:`\Sigma_k = \varnothing, k > 2` with the following interpretations: .. list-table:: :widths: 10 10 10 10 10 10 10 :header-rows: 1 * - :math:`x` - :math:`y` - :math:`\mathsf{and}(x,y)` - :math:`\mathsf{or}(x,y)` - :math:`\mathsf{not}(y)` - :math:`\mathsf{top}` - :math:`\mathsf{bot}` * - F - F - F - F - T - T - F * - F - T - F - T - F - - * - T - F - F - T - - - * - T - T - T - T - - - This algebra can be constructed in *ct4l* in the following way: .. code-block:: cpp using namespace std; using namespace ct4l; // build the domain auto domain = make_shared>(vector{"F", "T"}); // build the truth-tables auto tt_and = make_shared>({domain, 2, {"F"}, {{{"T", "T"}, {"T"}}}}); auto tt_or = make_shared>({domain, 2, {"T"}, {{{"F", "F"}, {"F"}}}}); auto tt_not = make_shared>({domain, 1, {"T"}, {{{"T"}, {"F"}}}}); auto tt_top = make_shared>({domain, 0, {"F"}}); auto tt_bot = make_shared>({domain, 0, {"T"}}); // build the algebra MultiAlgebra algebra { domain, { {{"and", 2}, tt_and}, {{"or", 2}, tt_or}, {{"not", 1}, tt_not}, {{"top", 0}, tt_top}, {{"bot", 0}, tt_bot}, } }; Accessing the algebra operations -------------------------------- We provide two ways to access the algebra operations: - by passing the symbol (if there are more than one connective with that symbol, gives the one with the least arity): .. code-block:: cpp auto tt_and_ptr = algebra["and"]; - by passing the connective, useful when you have connectives with the same symbol: .. code-block:: cpp auto tt_and_ptr = algebra[Connective{"and", 2}]; - by iterating: .. code-block:: cpp for (auto& [connective, truth_table_ptr] : algebra) { ... } Adding interpretations ---------------------- Use the :cpp:func:`ct4l::MultiAlgebra::interpret()` to interpret a new connective in a given algebra (modifying its signature): .. code-block:: cpp auto tt_botop = make_shared>({domain, 0, {"T", "F"}}); algebra.interpret("botop", tt_botop); API --- .. doxygenclass:: ct4l::MultiAlgebra :members: