1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
|
#if ! defined _Relation_h
#define _Relation_h 1
#include <omega/RelBody.h>
#include <omega/pres_cnstr.h>
#include <iostream>
#include <limits.h>
namespace omega {
//
// Relation representative.
// Body and representative are separated to do reference counting.
//
class Relation {
public:
Relation();
Relation(int n_input, int n_output = 0);
Relation(const Relation &r);
Relation(const Relation &r, Conjunct *c);
Relation &operator=(const Relation &r);
Relation(Rel_Body &r, int foo);
static Relation Null();
static Relation Empty(const Relation &R);
static Relation True(const Relation &R);
static Relation True(int setvars);
static Relation True(int in, int out);
static Relation False(const Relation &R);
static Relation False(int setvars);
static Relation False(int in, int out);
static Relation Unknown(const Relation &R);
static Relation Unknown(int setvars);
static Relation Unknown(int in, int out);
bool is_null() const;
~Relation();
inline F_Forall *add_forall()
{ return rel_body->add_forall(); }
inline F_Exists *add_exists()
{ return rel_body->add_exists(); }
inline F_And *add_and()
{ return rel_body->add_and(); }
inline F_And *and_with()
{ return rel_body->and_with(); }
inline F_Or *add_or()
{ return rel_body->add_or(); }
inline F_Not *add_not()
{ return rel_body->add_not(); }
inline void finalize()
{ rel_body->finalize(); }
inline bool is_finalized() const
{ return rel_body->finalized; }
inline bool is_set() const
{ return rel_body->is_set(); }
inline int n_inp() const
{ return rel_body->n_inp(); }
inline int n_out() const
{ return rel_body->n_out(); }
inline int n_set() const
{ return rel_body->n_set(); }
inline const Variable_ID_Tuple *global_decls() const
{ return rel_body->global_decls(); }
inline int max_ufs_arity() const
{ return rel_body->max_ufs_arity(); }
inline int max_ufs_arity_of_in() const
{ return rel_body->max_ufs_arity_of_in(); }
inline int max_ufs_arity_of_set() const
{ return rel_body->max_ufs_arity_of_set(); }
inline int max_ufs_arity_of_out() const
{ return rel_body->max_ufs_arity_of_out(); }
inline int max_shared_ufs_arity() const
{ return rel_body->max_shared_ufs_arity(); }
inline Variable_ID input_var(int nth)
{ return rel_body->input_var(nth); }
inline Variable_ID output_var(int nth)
{ return rel_body->output_var(nth); }
inline Variable_ID set_var(int nth)
{ return rel_body->set_var(nth); }
inline bool has_local(const Global_Var_ID G)
{ return rel_body->has_local(G); }
inline bool has_local(const Global_Var_ID G, Argument_Tuple of)
{ return rel_body->has_local(G, of); }
inline Variable_ID get_local(const Variable_ID v)
{ return split()->get_local(v); }
inline Variable_ID get_local(const Global_Var_ID G)
{ return split()->get_local(G); }
inline Variable_ID get_local(const Global_Var_ID G, Argument_Tuple of)
{ return split()->get_local(G, of); }
inline void name_input_var(int nth, Const_String S)
{ split()->name_input_var(nth, S); }
inline void name_output_var(int nth, Const_String S)
{ split()->name_output_var(nth, S); }
inline void name_set_var(int nth, Const_String S)
{ split()->name_set_var(nth, S); }
inline F_And *and_with_and()
{ return split()->and_with_and(); }
inline EQ_Handle and_with_EQ()
{ return split()->and_with_EQ(); }
inline EQ_Handle and_with_EQ(const Constraint_Handle &c)
{ return split()->and_with_EQ(c); }
inline GEQ_Handle and_with_GEQ()
{ return split()->and_with_GEQ(); }
inline GEQ_Handle and_with_GEQ(const Constraint_Handle &c)
{ return split()->and_with_GEQ(c); }
inline void print()
{ rel_body->print(); }
inline void print(FILE *output_file)
{ rel_body->print(output_file); }
inline void print_with_subs()
{ rel_body->print_with_subs(); }
inline void print_with_subs(FILE *output_file, bool printSym=false,
bool newline=true)
{ rel_body->print_with_subs(output_file, printSym, newline); }
inline std::string print_with_subs_to_string(bool printSym=false,
bool newline=true)
{ return rel_body->print_with_subs_to_string(printSym, newline); }
inline std::string print_outputs_with_subs_to_string()
{ return rel_body->print_outputs_with_subs_to_string(); }
inline std::string print_outputs_with_subs_to_string(int i)
{ return rel_body->print_outputs_with_subs_to_string(i); }
inline void prefix_print()
{ rel_body->prefix_print(); }
inline void prefix_print(FILE *output_file, int debug = 1)
{ rel_body->prefix_print(output_file, debug); }
inline std::string print_formula_to_string() {
return rel_body->print_formula_to_string();
}
void dimensions(int & ndim_all, int &ndim_domain);
inline bool is_lower_bound_satisfiable()
{ return rel_body->is_lower_bound_satisfiable(); }
inline bool is_upper_bound_satisfiable()
{ return rel_body->is_upper_bound_satisfiable(); }
inline bool is_satisfiable()
{ return rel_body->is_satisfiable(); }
inline bool is_tautology()
{ return rel_body->is_obvious_tautology(); } // for compatibility
inline bool is_obvious_tautology()
{ return rel_body->is_obvious_tautology(); }
inline bool is_definite_tautology()
{ return rel_body->is_definite_tautology(); }
// return x s.t. forall conjuncts c, c has >= x leading 0s
// for set, return -1 (pass this in, in case there are no conjuncts
inline int number_of_conjuncts()
{ return rel_body->query_DNF()->length(); }
// return x s.t. forall conjuncts c, c has >= x leading 0s
// for set, return -1 (pass this in, in case there are no conjuncts
inline int query_guaranteed_leading_0s()
{ return rel_body->query_DNF()->query_guaranteed_leading_0s(this->is_set() ? -1 : 0); }
// return x s.t. forall conjuncts c, c has <= x leading 0s
// if no conjuncts return min of input and output tuple sizes, or -1 if relation is a set
inline int query_possible_leading_0s()
{ return rel_body->query_DNF()->query_possible_leading_0s(
this->is_set()? -1 : min(n_inp(),n_out())); }
// return +-1 according to sign of leading dir, or 0 if we don't know
inline int query_leading_dir()
{ return rel_body->query_DNF()->query_leading_dir(); }
inline DNF* query_DNF()
{ return rel_body->query_DNF(); }
inline DNF* query_DNF(int rdt_conjs, int rdt_constrs)
{ return rel_body->query_DNF(rdt_conjs, rdt_constrs); }
inline void simplify(int rdt_conjs = 0, int rdt_constrs = 0)
{ rel_body->simplify(rdt_conjs, rdt_constrs); }
inline bool is_simplified()
{ return rel_body->is_simplified(); }
inline bool is_compressed() const
{ return rel_body->is_compressed(); }
inline Conjunct *rm_first_conjunct()
{ return rel_body->rm_first_conjunct(); }
inline Conjunct *single_conjunct()
{ return rel_body->single_conjunct(); }
inline bool has_single_conjunct()
{ return rel_body->has_single_conjunct(); }
void query_difference(Variable_ID v1, Variable_ID v2, coef_t &lowerBound, coef_t &upperBound, bool &guaranteed) {
rel_body->query_difference(v1, v2, lowerBound, upperBound, guaranteed);
}
void query_variable_bounds(Variable_ID v, coef_t &lowerBound, coef_t &upperBound) {
rel_body->query_variable_bounds(v,lowerBound,upperBound);
}
coef_t query_variable_mod(Variable_ID v, coef_t factor) {
assert(factor > 0);
return rel_body->query_variable_mod(v, factor);
}
int query_variable_mod(Variable_ID v, int factor) {
assert(sizeof(int) <= sizeof(coef_t));
coef_t result = rel_body->query_variable_mod(v, static_cast<coef_t>(factor));
if (result == posInfinity)
return INT_MAX;
else
return static_cast<int>(result);
}
inline void make_level_carried_to(int level)
{
split()->make_level_carried_to(level);
}
inline Relation extract_dnf_by_carried_level(int level, int direction)
{
return split()->extract_dnf_by_carried_level(level, direction);
}
inline void compress()
{
#if defined(INCLUDE_COMPRESSION)
split()->compress();
#endif
}
void uncompress()
{ rel_body->uncompress(); }
inline bool is_exact() const
{ return !(rel_body->unknown_uses() & (and_u | or_u)) ; }
inline bool is_inexact() const
{ return !is_exact(); }
inline bool is_unknown() const
{ return rel_body->is_unknown(); }
inline Rel_Unknown_Uses unknown_uses() const
{ return rel_body->unknown_uses(); }
void setup_names() {rel_body->setup_names();}
void copy_names(const Relation &r) {
copy_names(*r.rel_body);
};
void copy_names(Rel_Body &r);
private:
// Functions that have to create sets from relations:
friend class Rel_Body;
friend_rel_ops;
Rel_Body *split();
DNF* simplified_DNF() {
simplify();
return rel_body->simplified_DNF;
};
inline void invalidate_leading_info(int changed = -1)
{ split()->invalidate_leading_info(changed); }
inline void enforce_leading_info(int guaranteed, int possible, int dir)
{
split()->enforce_leading_info(guaranteed, possible, dir);
}
void makeSet();
void markAsSet();
void markAsRelation();
friend bool operator==(const Relation &, const Relation &);
void reverse_leading_dir_info()
{ split()->reverse_leading_dir_info(); }
void interpret_unknown_as_true()
{ split()->interpret_unknown_as_true(); }
void interpret_unknown_as_false()
{ split()->interpret_unknown_as_false(); }
Rel_Body *rel_body;
friend Relation merge_rels(Tuple<Relation> &R, const Tuple<std::map<Variable_ID, std::pair<Var_Kind, int> > > &mapping, const Tuple<bool> &inverse, Combine_Type ctype, int number_input, int number_output);
};
inline std::ostream & operator<<(std::ostream &o, Relation &R)
{
return o << R.print_with_subs_to_string();
}
Relation copy(const Relation &r);
} // namespace
#include <omega/Relations.h>
#endif
|