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
138
139
140
141
142
143
144
145
146
147
use {Description, Sentence, Proposition, Relation, Literal, Or, Not, Distinct, Function, Rule,
Variable, Constant, Clause, Term};
use Clause::{RuleClause, SentenceClause};
use Sentence::{PropSentence, RelSentence};
use Term::{ConstTerm, FuncTerm, VarTerm};
use Literal::{OrLit, NotLit, DistinctLit, PropLit, RelLit};
pub trait Visitor {
fn visit_clause(&mut self, _: &mut Clause) {}
fn visit_rule(&mut self, _: &mut Rule) {}
fn visit_sentence(&mut self, _: &mut Sentence) {}
fn visit_proposition(&mut self, _: &mut Proposition) {}
fn visit_relation(&mut self, _: &mut Relation) {}
fn visit_literal(&mut self, _: &mut Literal) {}
fn visit_term(&mut self, _: &mut Term) {}
fn visit_constant(&mut self, _: &mut Constant) {}
fn visit_or(&mut self, _: &mut Or) {}
fn visit_not(&mut self, _: &mut Not) {}
fn visit_distinct(&mut self, _: &mut Distinct) {}
fn visit_variable(&mut self, _: &mut Variable) {}
fn visit_function(&mut self, _: &mut Function) {}
}
pub fn visit<V: Visitor>(desc: &mut Description, visitor: &mut V) {
for clause in desc.clauses.iter_mut() {
visit_clause(clause, visitor);
}
}
pub fn visit_clause<V: Visitor>(clause: &mut Clause, visitor: &mut V) {
match clause {
&mut RuleClause(ref mut r) => visit_rule(r, visitor),
&mut SentenceClause(ref mut s) => visit_sentence(s, visitor)
}
visitor.visit_clause(clause);
}
pub fn visit_rule<V: Visitor>(rule: &mut Rule, visitor: &mut V) {
visit_sentence(&mut rule.head, visitor);
for l in rule.body.iter_mut() {
visit_literal(l, visitor);
}
visitor.visit_rule(rule);
}
pub fn visit_sentence<V: Visitor>(sentence: &mut Sentence, visitor: &mut V) {
match sentence {
&mut PropSentence(ref mut p) => visit_proposition(p, visitor),
&mut RelSentence(ref mut r) => visit_relation(r, visitor)
}
visitor.visit_sentence(sentence);
}
pub fn visit_proposition<V: Visitor>(proposition: &mut Proposition, visitor: &mut V) {
visit_constant(&mut proposition.name, visitor);
visitor.visit_proposition(proposition)
}
pub fn visit_relation<V: Visitor>(relation: &mut Relation, visitor: &mut V) {
visit_constant(&mut relation.name, visitor);
for t in relation.args.iter_mut() {
visit_term(t, visitor)
}
visitor.visit_relation(relation)
}
pub fn visit_literal<V: Visitor>(literal: &mut Literal, visitor: &mut V) {
match literal {
&mut OrLit(ref mut or) => visit_or(or, visitor),
&mut NotLit(ref mut not) => visit_not(not, visitor),
&mut DistinctLit(ref mut distinct) => visit_distinct(distinct, visitor),
&mut RelLit(ref mut rel) => visit_relation(rel, visitor),
&mut PropLit(ref mut prop) => visit_proposition(prop, visitor)
}
visitor.visit_literal(literal);
}
pub fn visit_term<V: Visitor>(term: &mut Term, visitor: &mut V) {
match term {
&mut ConstTerm(ref mut c) => visit_constant(c, visitor),
&mut FuncTerm(ref mut f) => visit_function(f, visitor),
&mut VarTerm(ref mut v) => visit_variable(v, visitor)
}
visitor.visit_term(term);
}
pub fn visit_constant<V: Visitor>(constant: &mut Constant, visitor: &mut V) {
visitor.visit_constant(constant);
}
pub fn visit_or<V: Visitor>(or: &mut Or, visitor: &mut V) {
for l in or.lits.iter_mut() {
visit_literal(l, visitor);
}
visitor.visit_or(or);
}
pub fn visit_not<V: Visitor>(not: &mut Not, visitor: &mut V) {
visit_literal(&mut not.lit, visitor);
visitor.visit_not(not);
}
pub fn visit_distinct<V: Visitor>(distinct: &mut Distinct, visitor: &mut V) {
visit_term(&mut distinct.term1, visitor);
visit_term(&mut distinct.term2, visitor);
visitor.visit_distinct(distinct);
}
pub fn visit_variable<V: Visitor>(variable: &mut Variable, visitor: &mut V) {
visit_constant(&mut variable.name, visitor);
visitor.visit_variable(variable);
}
pub fn visit_function<V: Visitor>(function: &mut Function, visitor: &mut V) {
visit_constant(&mut function.name, visitor);
for t in function.args.iter_mut() {
visit_term(t, visitor)
}
visitor.visit_function(function)
}