56 bool operator()(
bool& a,
bool b)
const {
66 struct false_factory {
67 bool operator()()
const {
77 struct bool_disjunct_lattic :
public property_space<bool, bool_or, false_factory> {};
80 using BoolDisjunctVar = ConstraintAnalysisVar<bool_disjunct_lattic>;
83 using BoolDisjunctConstraint = std::shared_ptr<Constraint<BoolDisjunctVar>>;
89 BoolDisjunctConstraint
isTrue(
const BoolDisjunctVar& var) {
90 struct C :
public Constraint<BoolDisjunctVar> {
92 C(BoolDisjunctVar var) : var(
std::move(var)) {}
93 bool update(Assignment<BoolDisjunctVar>& ass)
const override {
98 void print(std::ostream& out)
const override {
99 out << var <<
" is true";
102 return std::make_shared<C>(var);
112 BoolDisjunctConstraint imply(
const BoolDisjunctVar& a,
const BoolDisjunctVar&
b) {
113 return sub(a,
b,
"⇒");
123 BoolDisjunctConstraint imply(
const std::vector<BoolDisjunctVar>& vars,
const BoolDisjunctVar& res) {
124 struct C :
public Constraint<BoolDisjunctVar> {
126 std::vector<BoolDisjunctVar> vars;
128 C(BoolDisjunctVar res, std::vector<BoolDisjunctVar> vars)
129 : res(
std::move(res)), vars(
std::move(vars)) {}
131 bool update(Assignment<BoolDisjunctVar>& ass)
const override {
137 for (
const auto& cur : vars) {
147 void print(std::ostream& out)
const override {
148 out <<
join(vars,
" ∧ ") <<
" ⇒ " << res;
152 return std::make_shared<C>(res, vars);
155 struct GroundednessAnalysis :
public ConstraintAnalysis<BoolDisjunctVar> {
156 const RelationDetailCacheAnalysis&
relCache;
157 std::set<const Atom*>
ignore;
159 GroundednessAnalysis(
const TranslationUnit& tu)
160 :
relCache(*tu.getAnalysis<RelationDetailCacheAnalysis>()) {}
163 void visitAtom(
const Atom& cur)
override {
170 for (
const auto& arg : cur.getArguments()) {
171 addConstraint(
isTrue(getVar(arg)));
176 void visitNegation(
const Negation& cur)
override {
178 ignore.insert(cur.getAtom());
182 void visitClause(
const Clause& clause)
override {
183 if (
auto clauseHead = clause.getHead()) {
188 ignore.insert(clauseHead);
194 void visitBinaryConstraint(
const BinaryConstraint& cur)
override {
201 auto lhs = getVar(cur.getLHS());
202 auto rhs = getVar(cur.getRHS());
204 addConstraint(imply(
lhs,
rhs));
205 addConstraint(imply(
rhs,
lhs));
209 void visitRecordInit(
const RecordInit& init)
override {
210 auto cur = getVar(init);
212 std::vector<BoolDisjunctVar> vars;
215 for (
const auto& arg : init.getArguments()) {
216 auto arg_var = getVar(arg);
217 addConstraint(imply(cur, arg_var));
218 vars.push_back(arg_var);
222 addConstraint(imply(vars, cur));
225 void visitBranchInit(
const BranchInit& adt)
override {
226 auto branchVar = getVar(adt);
228 std::vector<BoolDisjunctVar> argVars;
231 for (
const auto* arg : adt.getArguments()) {
232 auto argVar = getVar(arg);
233 addConstraint(imply(branchVar, argVar));
234 argVars.push_back(argVar);
238 addConstraint(imply(argVars, branchVar));
242 void visitConstant(
const Constant& constant)
override {
243 addConstraint(
isTrue(getVar(constant)));
247 void visitAggregator(
const Aggregator& aggregator)
override {
248 addConstraint(
isTrue(getVar(aggregator)));
252 void visitFunctor(
const Functor& functor)
override {
253 auto var = getVar(functor);
254 std::vector<BoolDisjunctVar> varArgs;
255 for (
const auto& arg : functor.getArguments()) {
256 varArgs.push_back(getVar(arg));
258 addConstraint(imply(varArgs, var));
262 void visitTypeCast(
const ast::TypeCast& cast)
override {
263 addConstraint(imply(getVar(cast.getValue()), getVar(cast)));
272 std::map<const Argument*, bool>
getGroundedTerms(
const TranslationUnit& tu,
const Clause& clause) {
274 return GroundednessAnalysis(tu).analyse(clause);