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);