cvc5-cvc5-1.2.0.docs.theories.bags.rst Maven / Gradle / Ivy
The newest version!
Theory Reference: Bags
====================================
Finite Bags
-----------
cvc5 supports the theory of finite bags using the following sorts, constants,
functions and predicates.
For the C++ API examples in the table below, we assume that we have created
a `cvc5::Solver solver` object.
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| | SMTLIB language | C++ API |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Logic String | ``(set-logic ALL)`` | ``solver.setLogic("ALL");`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Sort | ``(Bag )`` | ``solver.mkBagSort(cvc5::Sort elementSort);`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Constants | ``(declare-const X (Bag String))`` | ``Sort s = solver.mkBagSort(solver.getStringSort());`` |
| | | |
| | | ``Term X = solver.mkConst(s, "X");`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Union disjoint | ``(bag.union_disjoint X Y)`` | ``Term Y = solver.mkConst(s, "Y");`` |
| | | |
| | | ``Term t = solver.mkTerm(Kind::BAG_UNION_DISJOINT, {X, Y});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Union max | ``(bag.union_max X Y)`` | ``Term Y = solver.mkConst(s, "Y");`` |
| | | |
| | | ``Term t = solver.mkTerm(Kind::BAG_UNION_MAX, {X, Y});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Intersection min | ``(bag.inter_min X Y)`` | ``Term t = solver.mkTerm(Kind::BAG_INTER_MIN, {X, Y});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Difference subtract | ``(bag.difference_subtract X Y)`` | ``Term t = solver.mkTerm(Kind::BAG_DIFFERENCE_SUBTRACT, {X, Y});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Duplicate elimination| ``(bag.setof X)`` | ``Term t = solver.mkTerm(Kind::BAG_SETOF, {X});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Membership | ``(bag.member x X)`` | ``Term x = solver.mkConst(solver.getStringSort(), "x");`` |
| | | |
| | | ``Term t = solver.mkTerm(Kind::BAG_MEMBER, {x, X});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Subbag | ``(bag.subbag X Y)`` | ``Term t = solver.mkTerm(Kind::BAG_SUBBAG, {X, Y});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Emptybag | ``(as bag.empty (Bag Int))`` | ``Term t = solver.mkEmptyBag(s);`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
| Make bag | ``(bag "a" 3)`` | ``Term t = solver.mkTerm(Kind::BAG_MAKE,`` |
| | | ``{solver.mkString("a"), solver.mkInteger(1)});`` |
+----------------------+----------------------------------------------+-------------------------------------------------------------------------+
Semantics
^^^^^^^^^
A bag (or a multiset) :math:`m` can be defined as a function from the domain of its elements
to the set of natural numbers (i.e., :math:`m : D \rightarrow \mathbb{N}`),
where :math:`m(e)` represents the multiplicity of element :math:`e` in the bag :math:`m`.
The semantics of supported bag operators is given in the table below.
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| Bag operator | cvc5 operator | Semantics |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| union disjoint :math:`m_1 \uplus m_2` | bag.union_disjoint | :math:`\forall e. \; (m_1 \uplus m_2)(e) = m_1(e) + m_2 (e)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| union max :math:`m_1 \cup m_2` | bag.union_max | :math:`\forall e. \; (m_1 \cup m_2)(e) = max(m_1(e), m_2 (e))` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| intersection :math:`m_1 \cap m_2` | bag.inter_min | :math:`\forall e. \; (m_1 \cap m_2)(e) = min(m_1(e), m_2 (e))` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| difference subtract :math:`m_1 \setminus m_2` | bag.difference_subtract | :math:`\forall e. \; (m_1 \setminus m_2)(e) = max(m_1(e) - m_2 (e), 0)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| difference remove :math:`m_1 \setminus\setminus m_2`| bag.difference_remove | :math:`\forall e. \; (m_1 \setminus\setminus m_2)(e) = ite(m_2(e) = 0, m_1(e), 0)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| setof :math:`\delta(m)` | bag.setof | :math:`\forall e. \; (\delta(m))(e) = ite(1 \leq m(e), 1, 0)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| subbag :math:`m_1 \subseteq m_2` | bag.subbag | :math:`\forall e. \; m_1(e) \leq m_2(e)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| equality :math:`m_1 = m_2` | = | :math:`\forall e. \; m_1(e) = m_2(e)` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
| membership :math:`e \in m` | bag.member | :math:`m(e) \geq 1` |
+-----------------------------------------------------+-------------------------+------------------------------------------------------------------------------------+
Below is a more extensive example on how to use finite bags:
.. api-examples::
/api/cpp/bags.cpp
/api/java/Bags.java
/api/python/bags.py
/api/smtlib/bags.smt2