GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/type_matcher.cpp Lines: 59 62 95.2 %
Date: 2021-05-22 Branches: 84 158 53.2 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner, Morgan Deters
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 a class representing a type matcher.
14
 */
15
16
#include "type_matcher.h"
17
18
namespace cvc5 {
19
20
1806
TypeMatcher::TypeMatcher(TypeNode dt)
21
{
22
1806
  Assert(dt.isDatatype());
23
1806
  addTypesFromDatatype(dt);
24
1806
}
25
26
1902
void TypeMatcher::addTypesFromDatatype(TypeNode dt)
27
{
28
3804
  std::vector<TypeNode> argTypes = dt.getParamTypes();
29
1902
  addTypes(argTypes);
30
1902
  Debug("typecheck-idt") << "instantiating matcher for " << dt << std::endl;
31
4285
  for (unsigned i = 0, narg = argTypes.size(); i < narg; ++i)
32
  {
33
2383
    if (dt.isParameterInstantiatedDatatype(i))
34
    {
35
1598
      Debug("typecheck-idt")
36
799
          << "++ instantiate param " << i << " : " << d_types[i] << std::endl;
37
799
      d_match[i] = d_types[i];
38
    }
39
  }
40
1902
}
41
42
2383
void TypeMatcher::addType(TypeNode t)
43
{
44
2383
  d_types.push_back(t);
45
2383
  d_match.push_back(TypeNode::null());
46
2383
}
47
48
1902
void TypeMatcher::addTypes(const std::vector<TypeNode>& types)
49
{
50
4285
  for (const TypeNode& t : types)
51
  {
52
2383
    addType(t);
53
  }
54
1902
}
55
56
5083
bool TypeMatcher::doMatching(TypeNode pattern, TypeNode tn)
57
{
58
10166
  Debug("typecheck-idt") << "doMatching() : " << pattern << " : " << tn
59
5083
                         << std::endl;
60
  std::vector<TypeNode>::iterator i =
61
5083
      std::find(d_types.begin(), d_types.end(), pattern);
62
5083
  if (i != d_types.end())
63
  {
64
1961
    size_t index = i - d_types.begin();
65
1961
    if (!d_match[index].isNull())
66
    {
67
894
      Debug("typecheck-idt")
68
447
          << "check subtype " << tn << " " << d_match[index] << std::endl;
69
894
      TypeNode tnn = TypeNode::leastCommonTypeNode(tn, d_match[index]);
70
      // recognize subtype relation
71
447
      if (!tnn.isNull())
72
      {
73
447
        d_match[index] = tnn;
74
447
        return true;
75
      }
76
      return false;
77
    }
78
1514
    d_match[index] = tn;
79
1514
    return true;
80
  }
81
3122
  else if (pattern == tn)
82
  {
83
1753
    return true;
84
  }
85
2738
  else if (pattern.getKind() != tn.getKind()
86
1369
           || pattern.getNumChildren() != tn.getNumChildren())
87
  {
88
31
    return false;
89
  }
90
1338
  else if (pattern.getNumChildren() == 0)
91
  {
92
    // fail if the type parameter or type constructors are different
93
    return pattern == tn;
94
  }
95
4263
  for (size_t j = 0, nchild = pattern.getNumChildren(); j < nchild; j++)
96
  {
97
2925
    if (!doMatching(pattern[j], tn[j]))
98
    {
99
      return false;
100
    }
101
  }
102
1338
  return true;
103
}
104
105
534
void TypeMatcher::getTypes(std::vector<TypeNode>& types) const
106
{
107
534
  types.clear();
108
1260
  for (const TypeNode& t : d_types)
109
  {
110
726
    types.push_back(t);
111
  }
112
534
}
113
1656
void TypeMatcher::getMatches(std::vector<TypeNode>& types) const
114
{
115
1656
  types.clear();
116
3728
  for (size_t i = 0, nmatch = d_match.size(); i < nmatch; i++)
117
  {
118
2072
    if (d_match[i].isNull())
119
    {
120
33
      types.push_back(d_types[i]);
121
    }
122
    else
123
    {
124
2039
      types.push_back(d_match[i]);
125
    }
126
  }
127
1656
}
128
129
28194
}  // namespace cvc5