GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/preprocessing/passes/sep_skolem_emp.cpp Lines: 49 51 96.1 %
Date: 2021-09-17 Branches: 93 182 51.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Yoni Zohar, Andrew Reynolds, Gereon Kremer
4
 *
5
 * This file is part of the cvc5 project.
6
 *
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
 * ****************************************************************************
12
 *
13
 * The sep-pre-skolem-emp preprocessing pass.
14
 */
15
16
#include "preprocessing/passes/sep_skolem_emp.h"
17
18
#include <string>
19
#include <unordered_map>
20
#include <vector>
21
22
#include "expr/node.h"
23
#include "expr/skolem_manager.h"
24
#include "preprocessing/assertion_pipeline.h"
25
#include "theory/quantifiers/quant_util.h"
26
#include "theory/rewriter.h"
27
#include "theory/theory.h"
28
29
namespace cvc5 {
30
namespace preprocessing {
31
namespace passes {
32
33
using namespace std;
34
using namespace cvc5::theory;
35
36
namespace {
37
38
3
Node preSkolemEmp(Node n,
39
                         bool pol,
40
                         std::map<bool, std::map<Node, Node>>& visited)
41
{
42
3
  std::map<Node, Node>::iterator it = visited[pol].find(n);
43
3
  if (it == visited[pol].end())
44
  {
45
3
    NodeManager* nm = NodeManager::currentNM();
46
3
    SkolemManager* sm = nm->getSkolemManager();
47
6
    Trace("sep-preprocess") << "Pre-skolem emp " << n << " with pol " << pol
48
3
                            << std::endl;
49
6
    Node ret = n;
50
3
    if (n.getKind() == kind::SEP_EMP)
51
    {
52
1
      if (!pol)
53
      {
54
2
        TypeNode tnx = n[0].getType();
55
2
        TypeNode tny = n[1].getType();
56
        Node x =
57
2
            sm->mkDummySkolem("ex", tnx, "skolem location for negated emp");
58
2
        Node y = sm->mkDummySkolem("ey", tny, "skolem data for negated emp");
59
        return nm
60
4
            ->mkNode(kind::SEP_STAR,
61
2
                     nm->mkNode(kind::SEP_PTO, x, y),
62
2
                     nm->mkConst(true))
63
1
            .negate();
64
      }
65
    }
66
2
    else if (n.getKind() != kind::FORALL && n.getNumChildren() > 0)
67
    {
68
1
      std::vector<Node> children;
69
1
      bool childChanged = false;
70
1
      if (n.getMetaKind() == kind::metakind::PARAMETERIZED)
71
      {
72
        children.push_back(n.getOperator());
73
      }
74
2
      for (unsigned i = 0; i < n.getNumChildren(); i++)
75
      {
76
        bool newPol, newHasPol;
77
1
        QuantPhaseReq::getPolarity(n, i, true, pol, newHasPol, newPol);
78
2
        Node nc = n[i];
79
1
        if (newHasPol)
80
        {
81
1
          nc = preSkolemEmp(n[i], newPol, visited);
82
1
          childChanged = childChanged || nc != n[i];
83
        }
84
1
        children.push_back(nc);
85
      }
86
1
      if (childChanged)
87
      {
88
1
        return nm->mkNode(n.getKind(), children);
89
      }
90
    }
91
1
    visited[pol][n] = ret;
92
1
    return n;
93
  }
94
  else
95
  {
96
    return it->second;
97
  }
98
}
99
100
}  // namespace
101
102
9942
SepSkolemEmp::SepSkolemEmp(PreprocessingPassContext* preprocContext)
103
9942
    : PreprocessingPass(preprocContext, "sep-skolem-emp"){};
104
105
1
PreprocessingPassResult SepSkolemEmp::applyInternal(
106
    AssertionPipeline* assertionsToPreprocess)
107
{
108
2
  std::map<bool, std::map<Node, Node>> visited;
109
3
  for (unsigned i = 0; i < assertionsToPreprocess->size(); ++i)
110
  {
111
4
    Node prev = (*assertionsToPreprocess)[i];
112
2
    bool pol = true;
113
4
    Node next = preSkolemEmp(prev, pol, visited);
114
2
    if (next != prev)
115
    {
116
1
      assertionsToPreprocess->replace(i, rewrite(next));
117
1
      Trace("sep-preprocess") << "*** Preprocess sep " << prev << endl;
118
2
      Trace("sep-preprocess") << "   ...got " << (*assertionsToPreprocess)[i]
119
1
                              << endl;
120
    }
121
2
    visited.clear();
122
  }
123
2
  return PreprocessingPassResult::NO_CONFLICT;
124
}
125
126
127
}  // namespace passes
128
}  // namespace preprocessing
129
29577
}  // namespace cvc5