GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arrays/proof_checker.cpp Lines: 44 60 73.3 %
Date: 2021-09-07 Branches: 108 424 25.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds
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 arrays proof checker.
14
 */
15
16
#include "theory/arrays/proof_checker.h"
17
18
#include "expr/skolem_manager.h"
19
#include "theory/arrays/skolem_cache.h"
20
#include "theory/arrays/theory_arrays_rewriter.h"
21
#include "theory/rewriter.h"
22
23
namespace cvc5 {
24
namespace theory {
25
namespace arrays {
26
27
3786
void ArraysProofRuleChecker::registerTo(ProofChecker* pc)
28
{
29
3786
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE, this);
30
3786
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE_CONTRA, this);
31
3786
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE_1, this);
32
3786
  pc->registerChecker(PfRule::ARRAYS_EXT, this);
33
3786
  pc->registerChecker(PfRule::ARRAYS_EQ_RANGE_EXPAND, this);
34
3786
}
35
36
465
Node ArraysProofRuleChecker::checkInternal(PfRule id,
37
                                           const std::vector<Node>& children,
38
                                           const std::vector<Node>& args)
39
{
40
465
  NodeManager* nm = NodeManager::currentNM();
41
465
  if (id == PfRule::ARRAYS_READ_OVER_WRITE)
42
  {
43
345
    Assert(children.size() == 1);
44
345
    Assert(args.size() == 1);
45
690
    Node ideq = children[0];
46
345
    if (ideq.getKind() != kind::NOT || ideq[0].getKind() != kind::EQUAL)
47
    {
48
      return Node::null();
49
    }
50
690
    Node lhs = args[0];
51
1035
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
52
1035
        || lhs[0][1] != ideq[0][0])
53
    {
54
      return Node::null();
55
    }
56
690
    Node rhs = nm->mkNode(kind::SELECT, lhs[0][0], ideq[0][1]);
57
345
    return lhs.eqNode(rhs);
58
  }
59
120
  else if (id == PfRule::ARRAYS_READ_OVER_WRITE_CONTRA)
60
  {
61
    Assert(children.size() == 1);
62
    Assert(args.empty());
63
    Node adeq = children[0];
64
    if (adeq.getKind() != kind::NOT || adeq[0].getKind() != kind::EQUAL)
65
    {
66
      return Node::null();
67
    }
68
    Node lhs = adeq[0][0];
69
    Node rhs = adeq[0][1];
70
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
71
        || rhs.getKind() != kind::SELECT || lhs[1] != rhs[1])
72
    {
73
      return Node::null();
74
    }
75
    return lhs[1].eqNode(lhs[0][1]);
76
  }
77
120
  if (id == PfRule::ARRAYS_READ_OVER_WRITE_1)
78
  {
79
104
    Assert(children.empty());
80
104
    Assert(args.size() == 1);
81
208
    Node lhs = args[0];
82
312
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
83
312
        || lhs[0][1] != lhs[1])
84
    {
85
      return Node::null();
86
    }
87
208
    Node rhs = lhs[0][2];
88
104
    return lhs.eqNode(rhs);
89
  }
90
16
  if (id == PfRule::ARRAYS_EXT)
91
  {
92
13
    Assert(children.size() == 1);
93
13
    Assert(args.empty());
94
26
    Node adeq = children[0];
95
39
    if (adeq.getKind() != kind::NOT || adeq[0].getKind() != kind::EQUAL
96
39
        || !adeq[0][0].getType().isArray())
97
    {
98
      return Node::null();
99
    }
100
26
    Node k = SkolemCache::getExtIndexSkolem(adeq);
101
26
    Node a = adeq[0][0];
102
26
    Node b = adeq[0][1];
103
26
    Node as = nm->mkNode(kind::SELECT, a, k);
104
26
    Node bs = nm->mkNode(kind::SELECT, b, k);
105
13
    return as.eqNode(bs).notNode();
106
  }
107
3
  if (id == PfRule::ARRAYS_EQ_RANGE_EXPAND)
108
  {
109
6
    Node expandedEqRange = TheoryArraysRewriter::expandEqRange(args[0]);
110
3
    return args[0].eqNode(expandedEqRange);
111
  }
112
  // no rule
113
  return Node::null();
114
}
115
116
}  // namespace arrays
117
}  // namespace theory
118
29502
}  // namespace cvc5