-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGraphBuilder.cpp
181 lines (148 loc) · 5.12 KB
/
GraphBuilder.cpp
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/***************************************************************************
* Copyright (C) 2009 by Mushthofa *
* unintendedchoice@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/**
* @file GraphBuilder.h
* @author Roman Schindlauer, Mushthofa
*
* @brief Class to provide methods for generating the dependency graph
*
*
*/
#include "GraphBuilder.h"
#include "Registry.h"
void GraphBuilder::run(const Program& program, NodeGraph& nodegraph)
{
//
// empty the NodeGraph
//
nodegraph.reset();
//
// go through all rules of the given program
//
for (Program::iterator r = program.begin();
r != program.end();
++r)
{
//
// all nodes of the current rule's head
//
std::vector<AtomNodePtr> currentHeadNodes;
//
// go through entire head disjunction
//
const HeadExpr_t& head = (*r)->getHead();
HeadList_t headlist = head.first;
for (HeadList_t::const_iterator hi = headlist.begin();
hi != headlist.end();
++hi)
{
//
// add a head atom node. This function will take care of also adding
// the appropriate unifying dependency for all existing nodes.
//
AtomNodePtr hn = nodegraph.addUniqueHeadNode(*hi);
//
// go through all head atoms that were alreay created for this rule
//
for (std::vector<AtomNodePtr>::iterator currhead = currentHeadNodes.begin();
currhead != currentHeadNodes.end();
++currhead)
{
//
// and add disjunctive dependency
//
Dependency::addDep(*r, hn, *currhead, Dependency::DISJUNCTIVE);
Dependency::addDep(*r, *currhead, hn, Dependency::DISJUNCTIVE);
}
//
// add this atom to current head
//
currentHeadNodes.push_back(hn);
}
//
// constraint: create virtual head node to keep the rule
//
if (headlist.size() == 0)
{
AtomPtr va = Registry::Instance()->storeAtom(new DummyAtom());
AtomNodePtr vn = nodegraph.addUniqueHeadNode(va);
currentHeadNodes.push_back(vn);
}
//std::vector<AtomNodePtr> currentOrdinaryBodyNodes;
std::vector<AtomNodePtr> currentBodyNodes;
//
// go through rule body
//
const BodyExpr_t& body = (*r)->getBody();
BodyList_t bodylist = body.first;
for (BodyList_t::const_iterator li = bodylist.begin();
li != bodylist.end();
++li)
{
//
// add a body atom node. This function will take care of also adding the appropriate
// unifying dependency for all existing nodes.
//
AtomNodePtr bn = nodegraph.addUniqueBodyNode((*li)->getAtom());
//if ((typeid(*((*li)->getAtom())) == typeid(Atom)) &&
if (!(*li)->isNAF())
currentBodyNodes.push_back(bn);
//
// add dependency from this body atom to each head atom
//
for (std::vector<AtomNodePtr>::iterator currhead = currentHeadNodes.begin();
currhead != currentHeadNodes.end();
++currhead)
{
if ((*li)->isNAF())
Dependency::addDep(*r, bn, *currhead, Dependency::NEG_PRECEDING);
else
Dependency::addDep(*r, bn, *currhead, Dependency::PRECEDING);
/* We set up a dummy dependency between the body literals and the empty head
literals to force a constraint to be included in the components where its
body literals are resolved
Eg:
a v b :- c.
:- not a.
by setting up a dummy dependecy from a to _ (empty head), we force
the constraint :- not a to be in an scc along with a v b :- c.
*/
if(headlist.size() == 0)
{
if ((*li)->isNAF())
Dependency::addDep(*r, *currhead, bn, Dependency::NEG_PRECEDING);
else
Dependency::addDep(*r, *currhead, bn, Dependency::PRECEDING);
}
}
} // body finished
}
}
void GraphBuilder::dumpGraph(const NodeGraph& nodegraph, std::ostream& out) const
{
out << "Dependency graph - Program Nodes:" << std::endl;
for (std::vector<AtomNodePtr>::const_iterator node = nodegraph.getNodes().begin();
node != nodegraph.getNodes().end();
++node)
{
out << **node << std::endl;
}
out << std::endl;
}