summaryrefslogtreecommitdiff
path: root/src/theory/arrays/inference_manager.cpp
blob: ec6890293027f8dda484ab333a7088b35abfbe9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*********************                                                        */
/*! \file inference_manager.cpp
 ** \verbatim
 ** Top contributors (to current version):
 **   Andrew Reynolds
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
 ** in the top-level source directory and their institutional affiliations.
 ** All rights reserved.  See the file COPYING in the top-level source
 ** directory for licensing information.\endverbatim
 **
 ** \brief Arrays inference manager
 **/

#include "theory/arrays/inference_manager.h"

#include "options/smt_options.h"
#include "theory/theory.h"
#include "theory/uf/equality_engine.h"

using namespace CVC4::kind;

namespace CVC4 {
namespace theory {
namespace arrays {

InferenceManager::InferenceManager(Theory& t,
                                   TheoryState& state,
                                   ProofNodeManager* pnm)
    : TheoryInferenceManager(t, state, pnm),
      d_lemmaPg(pnm ? new EagerProofGenerator(pnm,
                                              state.getUserContext(),
                                              "ArrayLemmaProofGenerator")
                    : nullptr)
{
}

bool InferenceManager::assertInference(TNode atom,
                                       bool polarity,
                                       TNode reason,
                                       PfRule id)
{
  Trace("arrays-infer") << "TheoryArrays::assertInference: "
                        << (polarity ? Node(atom) : atom.notNode()) << " by "
                        << reason << "; " << id << std::endl;
  Assert(atom.getKind() == EQUAL);
  // if proofs are enabled, we determine which proof rule to add, otherwise
  // we simply assert the internal fact
  if (isProofEnabled())
  {
    Node fact = polarity ? Node(atom) : atom.notNode();
    std::vector<Node> children;
    std::vector<Node> args;
    // convert to proof rule application
    convert(id, fact, reason, children, args);
    return assertInternalFact(atom, polarity, id, children, args);
  }
  return assertInternalFact(atom, polarity, reason);
}

bool InferenceManager::arrayLemma(
    Node conc, Node exp, PfRule id, LemmaProperty p, bool doCache)
{
  Trace("arrays-infer") << "TheoryArrays::arrayLemma: " << conc << " by " << exp
                        << "; " << id << std::endl;
  NodeManager* nm = NodeManager::currentNM();
  if (isProofEnabled())
  {
    std::vector<Node> children;
    std::vector<Node> args;
    // convert to proof rule application
    convert(id, conc, exp, children, args);
    // make the trusted lemma based on the eager proof generator and send
    TrustNode tlem = d_lemmaPg->mkTrustNode(conc, id, children, args);
    return trustedLemma(tlem, p, doCache);
  }
  // send lemma without proofs
  Node lem = nm->mkNode(IMPLIES, exp, conc);
  return lemma(lem, p, doCache);
}

void InferenceManager::convert(PfRule& id,
                               Node conc,
                               Node exp,
                               std::vector<Node>& children,
                               std::vector<Node>& args)
{
  // note that children must contain something equivalent to exp,
  // regardless of the PfRule.
  switch (id)
  {
    case PfRule::MACRO_SR_PRED_INTRO:
      Assert(exp.isConst());
      args.push_back(conc);
      break;
    case PfRule::ARRAYS_READ_OVER_WRITE:
      if (exp.isConst())
      {
        // Premise can be shown by rewriting, use standard predicate intro rule.
        // This is the case where we have 2 constant indices.
        id = PfRule::MACRO_SR_PRED_INTRO;
        args.push_back(conc);
      }
      else
      {
        children.push_back(exp);
        args.push_back(conc[0]);
      }
      break;
    case PfRule::ARRAYS_READ_OVER_WRITE_CONTRA: children.push_back(exp); break;
    case PfRule::ARRAYS_READ_OVER_WRITE_1:
      Assert(exp.isConst());
      args.push_back(conc[0]);
      break;
    case PfRule::ARRAYS_EXT: children.push_back(exp); break;
    default:
      // unknown rule, should never happen
      Assert(false);
      children.push_back(exp);
      args.push_back(conc);
      id = PfRule::ARRAYS_TRUST;
      break;
  }
}

}  // namespace arrays
}  // namespace theory
}  // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback