1 /******************************************************************************
2 * Top contributors (to current version):
5 * This file is part of the cvc5 project.
7 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 * in the top-level source directory and their institutional affiliations.
9 * All rights reserved. See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
13 * Utility functions for bags.
16 #include <expr/node.h>
18 #include "cvc5_private.h"
20 #ifndef CVC5__THEORY__BAGS__UTILS_H
21 #define CVC5__THEORY__BAGS__UTILS_H
31 * @param bagType type of bags
32 * @param bags a vector of bag nodes
33 * @return disjoint union of these bags
35 static Node
computeDisjointUnion(TypeNode bagType
,
36 const std::vector
<Node
>& bags
);
38 * Returns true if n is considered a to be a (canonical) constant bag value.
39 * A canonical bag value is one whose AST is:
40 * (bag.union_disjoint (bag e1 c1) ...
41 * (bag.union_disjoint (bag e_{n-1} c_{n-1}) (bag e_n c_n))))
42 * where c1 ... cn are positive integers, e1 ... en are constants, and the
43 * node identifier of these constants are such that: e1 < ... < en.
44 * Also handles the corner cases of empty bag and bag constructed by bag
46 static bool isConstant(TNode n
);
48 * check whether all children of the given node are constants
50 static bool areChildrenConstants(TNode n
);
52 * evaluate the node n to a constant value.
53 * As a precondition, children of n should be constants.
55 static Node
evaluate(TNode n
);
58 * get the elements along with their multiplicities in a given bag
59 * @param n a constant node whose type is a bag
60 * @return a map whose keys are constant elements and values are
63 static std::map
<Node
, Rational
> getBagElements(TNode n
);
66 * construct a constant bag from constant elements
67 * @param t the type of the returned bag
68 * @param elements a map whose keys are constant elements and values are
70 * @return a constant bag that contains
72 static Node
constructConstantBagFromElements(
73 TypeNode t
, const std::map
<Node
, Rational
>& elements
);
76 * construct a constant bag from node elements
77 * @param t the type of the returned bag
78 * @param elements a map whose keys are constant elements and values are
80 * @return a constant bag that contains
82 static Node
constructBagFromElements(TypeNode t
,
83 const std::map
<Node
, Node
>& elements
);
86 * @param n has the form (bag.fold f t A) where A is a constant bag
87 * @return a single value which is the result of the fold
89 static Node
evaluateBagFold(TNode n
);
92 * @param n has the form (bag.filter p A) where A is a constant bag
93 * @return A filtered with predicate p
95 static Node
evaluateBagFilter(TNode n
);
98 * @param n of the form (table.product A B) where A , B of types (Bag T1),
99 * (Bag T2) respectively.
100 * @param e1 a tuple of type T1 of the form (tuple a1 ... an)
101 * @param e2 a tuple of type T2 of the form (tuple b1 ... bn)
102 * @return (tuple a1 ... an b1 ... bn)
104 static Node
constructProductTuple(TNode n
, TNode e1
, TNode e2
);
107 * @param n of the form (table.product A B) where A, B are constants
108 * @return the evaluation of the cross product of A B
110 static Node
evaluateProduct(TNode n
);
114 * a high order helper function that return a constant bag that is the result
115 * of (op A B) where op is a binary operator and A, B are constant bags.
116 * The result is computed from the elements of A (elementsA with iterator itA)
117 * and elements of B (elementsB with iterator itB).
118 * The arguments below specify how these iterators are used to generate the
119 * elements of the result (elements).
120 * @param n a node whose kind is a binary operator (bag.union_disjoint,
121 * union_max, intersection_min, difference_subtract, difference_remove) and
122 * whose children are constant bags.
123 * @param equal a lambda expression that receives (elements, itA, itB) and
124 * specify the action that needs to be taken when the elements of itA, itB are
126 * @param less a lambda expression that receives (elements, itA, itB) and
127 * specify the action that needs to be taken when the element itA is less than
128 * the element of itB.
129 * @param greaterOrEqual less a lambda expression that receives (elements,
130 * itA, itB) and specify the action that needs to be taken when the element
131 * itA is greater than or equal than the element of itB.
132 * @param remainderOfA a lambda expression that receives (elements, elementsA,
133 * itA) and specify the action that needs to be taken to the remaining
134 * elements of A when all elements of B are visited.
135 * @param remainderOfB a lambda expression that receives (elements, elementsB,
136 * itB) and specify the action that needs to be taken to the remaining
137 * elements of B when all elements of A are visited.
138 * @return a constant bag that the result of (op n[0] n[1])
140 template <typename T1
, typename T2
, typename T3
, typename T4
, typename T5
>
141 static Node
evaluateBinaryOperation(const TNode
& n
,
148 * evaluate n as follows:
149 * - (bag a 0) = (as bag.empty T) where T is the type of the original bag
150 * - (bag a (-c)) = (as bag.empty T) where T is the type the original bag,
151 * and c > 0 is a constant
153 static Node
evaluateMakeBag(TNode n
);
156 * returns the multiplicity in a constant bag
157 * @param n has the form (bag.count x A) where x, A are constants
158 * @return the multiplicity of element x in bag A.
160 static Node
evaluateBagCount(TNode n
);
163 * @param n has the form (bag.duplicate_removal A) where A is a constant bag
164 * @return a constant bag constructed from the elements in A where each
165 * element has multiplicity one
167 static Node
evaluateDuplicateRemoval(TNode n
);
170 * evaluates union disjoint node such that the returned node is a canonical
171 * bag that has the form
172 * (bag.union_disjoint (bag e1 c1) ...
173 * (bag.union_disjoint * (bag e_{n-1} c_{n-1}) (bag e_n c_n)))) where
174 * c1... cn are positive integers, e1 ... en are constants, and the node
175 * identifier of these constants are such that: e1 < ... < en.
176 * @param n has the form (bag.union_disjoint A B) where A, B are constant bags
177 * @return the union disjoint of A and B
179 static Node
evaluateUnionDisjoint(TNode n
);
181 * @param n has the form (bag.union_max A B) where A, B are constant bags
182 * @return the union max of A and B
184 static Node
evaluateUnionMax(TNode n
);
186 * @param n has the form (bag.inter_min A B) where A, B are constant bags
187 * @return the intersection min of A and B
189 static Node
evaluateIntersectionMin(TNode n
);
191 * @param n has the form (bag.difference_subtract A B) where A, B are constant
193 * @return the difference subtract of A and B
195 static Node
evaluateDifferenceSubtract(TNode n
);
197 * @param n has the form (bag.difference_remove A B) where A, B are constant
199 * @return the difference remove of A and B
201 static Node
evaluateDifferenceRemove(TNode n
);
203 * @param n has the form (bag.choose A) where A is a constant bag
204 * @return x if n has the form (bag.choose (bag x c)). Otherwise an error is
207 static Node
evaluateChoose(TNode n
);
209 * @param n has the form (bag.card A) where A is a constant bag
210 * @return the number of elements in bag A
212 static Node
evaluateCard(TNode n
);
214 * @param n has the form (bag.is_singleton A) where A is a constant bag
215 * @return whether the bag A has cardinality one.
217 static Node
evaluateIsSingleton(TNode n
);
219 * @param n has the form (bag.from_set A) where A is a constant set
220 * @return a constant bag that contains exactly the elements in A.
222 static Node
evaluateFromSet(TNode n
);
224 * @param n has the form (bag.to_set A) where A is a constant bag
225 * @return a constant set constructed from the elements in A.
227 static Node
evaluateToSet(TNode n
);
229 * @param n has the form (bag.map f A) where A is a constant bag
230 * @return a constant bag constructed from the images of elements in A.
232 static Node
evaluateBagMap(TNode n
);
235 } // namespace theory
238 #endif /* CVC5__THEORY__BAGS__UTILS_H */