-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcorpus.hpp
137 lines (112 loc) · 3.87 KB
/
corpus.hpp
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
129
130
131
132
133
134
135
136
137
#pragma once
#include <pomagma/atlas/macro/util.hpp>
#include <pomagma/analyst/approximate.hpp>
#include <pomagma/util/hash_map.hpp>
#include <unordered_set>
namespace pomagma {
class Corpus {
class Dag;
class Reducer;
class Parser;
public:
struct Term {
enum Arity {
OB,
HOLE,
NULLARY_FUNCTION,
INJECTIVE_FUNCTION,
BINARY_FUNCTION,
SYMMETRIC_FUNCTION,
UNARY_RELATION,
BINARY_RELATION,
VARIABLE // must be last to match CachedApproximator::Term::Arity
};
struct Hash {
std::hash<std::string> hash_string;
std::hash<const Term *> hash_pointer;
uint64_t operator()(const Term &x) const {
FNV_hash::HashState state;
state.add(x.arity);
state.add(hash_string(x.name));
state.add(hash_pointer(x.arg0));
state.add(hash_pointer(x.arg1));
state.add(x.ob);
return state.get();
}
};
bool operator==(const Term &o) const {
return arity == o.arity and name == o.name and arg0 == o.arg0 and
arg1 == o.arg1 and ob == o.ob;
}
bool operator!=(const Term &o) const { return not operator==(o); }
Term() {}
Term(Ob o) : arity(OB), name(), arg0(nullptr), arg1(nullptr), ob(o) {}
Term(Arity a, const std::string &n = "", const Term *a0 = nullptr,
const Term *a1 = nullptr)
: arity(a), name(n), arg0(a0), arg1(a1), ob(0) {}
Arity arity;
std::string name;
const Term *arg0;
const Term *arg1;
Ob ob;
};
template <class T>
struct LineOf {
std::string maybe_name;
T body;
bool has_name() const { return not maybe_name.empty(); }
};
class Linker {
public:
const Term *link(const Term *term);
const Term *approximate(const Term *term, size_t depth);
private:
friend class Corpus;
Linker(Dag &dag, std::vector<std::string> &error_log);
void define(const std::string &name, const Term *term);
void finish();
const Term *approximate(const Term *term);
static void accum_free(const Term *term,
std::unordered_set<const Term *> &free);
Dag &m_dag;
std::vector<std::string> &m_error_log;
std::unordered_map<const Term *, const Term *> m_definitions;
std::unordered_set<const Term *> m_ground_terms;
size_t m_temp_max_depth;
std::unordered_map<const Term *, size_t> m_temp_depths;
};
struct Histogram {
std::unordered_map<std::string, size_t> symbols;
std::unordered_map<Ob, size_t> obs;
void add(const Term *term) {
switch (term->arity) {
case Term::OB:
++obs[term->ob];
break;
case Term::NULLARY_FUNCTION:
case Term::INJECTIVE_FUNCTION:
case Term::BINARY_FUNCTION:
case Term::SYMMETRIC_FUNCTION:
case Term::UNARY_RELATION:
case Term::BINARY_RELATION:
++symbols[term->name];
break;
case Term::HOLE:
case Term::VARIABLE:
break;
}
}
};
explicit Corpus(Signature &signature);
~Corpus();
Linker linker(const std::vector<LineOf<std::string>> &lines,
std::vector<std::string> &error_log);
std::vector<LineOf<const Term *>> parse(
const std::vector<LineOf<std::string>> &lines, Linker &linker,
std::vector<std::string> &error_log);
const Histogram &histogram() const;
private:
Signature &m_signature;
Dag &m_dag;
};
} // namespace pomagma