GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/proof_checker.cpp Lines: 42 58 72.4 %
Date: 2021-05-22 Branches: 67 270 24.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Aina Niemetz
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
 * Implementation of quantifiers proof checker.
14
 */
15
16
#include "theory/quantifiers/proof_checker.h"
17
18
#include "expr/node_algorithm.h"
19
#include "expr/skolem_manager.h"
20
#include "theory/builtin/proof_checker.h"
21
22
using namespace cvc5::kind;
23
24
namespace cvc5 {
25
namespace theory {
26
namespace quantifiers {
27
28
3600
void QuantifiersProofRuleChecker::registerTo(ProofChecker* pc)
29
{
30
  // add checkers
31
3600
  pc->registerChecker(PfRule::SKOLEM_INTRO, this);
32
3600
  pc->registerChecker(PfRule::EXISTS_INTRO, this);
33
3600
  pc->registerChecker(PfRule::SKOLEMIZE, this);
34
3600
  pc->registerChecker(PfRule::INSTANTIATE, this);
35
3600
}
36
37
12589
Node QuantifiersProofRuleChecker::checkInternal(
38
    PfRule id, const std::vector<Node>& children, const std::vector<Node>& args)
39
{
40
12589
  NodeManager* nm = NodeManager::currentNM();
41
12589
  SkolemManager* sm = nm->getSkolemManager();
42
  // compute what was proven
43
12589
  if (id == PfRule::EXISTS_INTRO)
44
  {
45
    Assert(children.size() == 1);
46
    Assert(args.size() == 1);
47
    Node p = children[0];
48
    Node exists = args[0];
49
    if (exists.getKind() != kind::EXISTS || exists[0].getNumChildren() != 1)
50
    {
51
      return Node::null();
52
    }
53
    std::unordered_map<Node, Node> subs;
54
    if (!expr::match(exists[1], p, subs))
55
    {
56
      return Node::null();
57
    }
58
    // substitution must contain only the variable of the existential
59
    for (const std::pair<const Node, Node>& s : subs)
60
    {
61
      if (s.first != exists[0][0])
62
      {
63
        return Node::null();
64
      }
65
    }
66
    return exists;
67
  }
68
12589
  else if (id == PfRule::SKOLEM_INTRO)
69
  {
70
3487
    Assert(children.empty());
71
3487
    Assert(args.size() == 1);
72
6974
    Node t = SkolemManager::getOriginalForm(args[0]);
73
3487
    return args[0].eqNode(t);
74
  }
75
9102
  else if (id == PfRule::SKOLEMIZE)
76
  {
77
462
    Assert(children.size() == 1);
78
462
    Assert(args.empty());
79
    // can use either negated FORALL or EXISTS
80
924
    if (children[0].getKind() != EXISTS
81
924
        && (children[0].getKind() != NOT || children[0][0].getKind() != FORALL))
82
    {
83
      return Node::null();
84
    }
85
924
    Node exists;
86
462
    if (children[0].getKind() == EXISTS)
87
    {
88
111
      exists = children[0];
89
    }
90
    else
91
    {
92
702
      std::vector<Node> echildren(children[0][0].begin(), children[0][0].end());
93
351
      echildren[1] = echildren[1].notNode();
94
351
      exists = nm->mkNode(EXISTS, echildren);
95
    }
96
924
    std::vector<Node> skolems;
97
924
    Node res = sm->mkSkolemize(exists, skolems, "k");
98
462
    return res;
99
  }
100
8640
  else if (id == PfRule::INSTANTIATE)
101
  {
102
8640
    Assert(children.size() == 1);
103
17280
    if (children[0].getKind() != FORALL
104
17280
        || args.size() != children[0][0].getNumChildren())
105
    {
106
      return Node::null();
107
    }
108
17280
    Node body = children[0][1];
109
17280
    std::vector<Node> vars;
110
17280
    std::vector<Node> subs;
111
30832
    for (unsigned i = 0, nargs = args.size(); i < nargs; i++)
112
    {
113
22192
      vars.push_back(children[0][0][i]);
114
22192
      subs.push_back(args[i]);
115
    }
116
    Node inst =
117
17280
        body.substitute(vars.begin(), vars.end(), subs.begin(), subs.end());
118
8640
    return inst;
119
  }
120
121
  // no rule
122
  return Node::null();
123
}
124
125
}  // namespace quantifiers
126
}  // namespace theory
127
28194
}  // namespace cvc5