-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdag-simple.h
240 lines (203 loc) · 6.13 KB
/
dag-simple.h
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/* PET
* Platform for Experimentation with efficient HPSG processing Techniques
* (C) 1999 - 2002 Ulrich Callmeier [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** \file dag-simple.h
* Simple typed dags.
*/
#ifndef _DAG_H_
#define _DAG_H_
/** Simple typed dags: the dag nodes */
struct dag_node
{
/** The forward pointer to relate unified nodes during unification. This is
* like a union-find data structure.
*/
struct dag_node *forward;
/** The type ID of this node */
int type;
/** The outgoing arcs list (single linked) of this node, maybe \c NULL */
struct dag_arc *arcs;
/** @name Copy Slot
* The copy slot, protected by a generation counter
*/
/*@{*/
struct dag_node *copy; int copy_generation;
/*@}*/
#ifdef FLOP
/** @name Visit Slot
* A slot to mark visits throughout traversal, protected by a generation
* counter.
*/
/*@{*/
int visit; int visit_generation;
/*@}*/
#endif
};
/** Simple typed dags: the dag arcs */
struct dag_arc
{
/** The attribute ID of this arc */
int attr;
/** The dag node pointed to by this arc */
struct dag_node *val;
/** The next arc in this arc list, maybe \c NULL */
struct dag_arc *next;
};
#include "dag-alloc.h"
/** The generation counter for ordinary copies */
extern int copy_generation;
/** The generation counter used during well-formedness unifications */
extern int copy_wf_generation;
/** Get the copy slot of \a dag, checking the \a generation.
* \return NULL, if \a generation is not the current generation, the value of
* the copy slot otherwise.
*/
inline dag_node *dag_get_copy(dag_node *dag, int generation)
{
if(generation != dag->copy_generation)
return 0;
else
return dag->copy;
}
/** Set the copy slot of \a dag to \a copy.
* The generation counter of the slot is set to \a generation, thereby
* validating the slot.
* \return the \a copy node.
*/
inline dag_node *dag_set_copy(dag_node *dag, dag_node *copy, int generation)
{
dag->copy_generation = generation;
return dag->copy = copy;
}
/** Increase the global generation counters to invalidate all copy slots. */
inline void dag_invalidate_copy()
{
if(copy_wf_generation > copy_generation)
copy_generation = copy_wf_generation + 1;
else
++copy_generation;
copy_wf_generation = copy_generation;
}
#ifdef FLOP
/** @name Visit Slot
* A seperate visited field generation counter that is necessary only for type
* expansion.
* The functionality is the same as with the copy generation counter.
*/
/*@{*/
extern int visit_generation;
inline int dag_get_visit(dag_node *dag)
{
if(visit_generation != dag->visit_generation)
return 0;
else
return dag->visit;
}
inline int dag_set_visit(dag_node *dag, int visit)
{
dag->visit_generation = visit_generation;
return dag->visit=visit;
}
inline void dag_invalidate_visited()
{
++visit_generation;
}
/*@}*/
#else
/** @name Visit Slot
* `overload' the copy slot to obtain the desired functionality for traversal
*/
/*@{*/
inline int dag_get_visit(dag_node *dag)
{
if(copy_generation != dag->copy_generation)
return 0;
else
return (int) dag->copy;
}
inline int dag_set_visit(dag_node *dag, int visit)
{
dag->copy_generation = copy_generation;
return (int) (dag->copy = (dag_node *) visit);
}
inline void dag_invalidate_visited()
{
if(copy_wf_generation > copy_generation)
copy_generation = copy_wf_generation + 1;
else
++copy_generation;
copy_wf_generation = copy_generation;
}
/*@}*/
#endif
/** Follow the forward links to the node that represents this dag at the
* moment.
*/
inline dag_node *dag_deref(dag_node *dag)
{
while(dag->forward != dag)
dag = dag->forward;
return dag;
}
inline const dag_node *dag_deref(const dag_node *dag)
{
while(dag->forward != dag)
dag = dag->forward;
return dag;
}
/** Return \c true if \a dag has no arcs */
inline bool dag_framed(const dag_node *dag)
{
if(dag == 0) return false;
dag = dag_deref(dag);
return dag->arcs != 0;
}
inline const dag_arc *dag_get_comp_arcs(const dag_node *dag) { return NULL; }
#ifdef FLOP
/** special handling of the dag visit flag in type expansion */
extern bool unify_reset_visited;
#endif
/** make \a v the \a n th argument of a new dag containing only an incomplete
* list and return this dag.
*/
dag_node *make_nth_arg(int n, dag_node *v);
/** Clone \a src and return the copy */
dag_node *dag_copy(dag_node *src);
/** @name Wroblewski Unification
An implementation of unify1 and unify2 of Wroblewski(1987) with
changes for welltyped unification.
Unify2 is buggy in the paper (for certain cases of convergent arcs),
fixing it requires a third, directed mode of unification where only
one of the input dags is modified. This resembles `into' unification
a la Ciortuz(2000). This directed mode has to fall back to
destructive unification for nodes copied previously within the same
unification context - otherwise we'd have to dereference the copy slot
(since we could get chains of copies) */
/*@{*/
/** Destructive unification. */
dag_node *dag_unify1(dag_node *dag1, dag_node *dag2);
/** Non-destructive unification. */
dag_node *dag_unify2(dag_node *dag1, dag_node *dag2);
/** Semi-destructive unification */
dag_node *dag_unify3(dag_node *dag1, dag_node *dag2);
/*@}*/
/** Return \c true if \a dag contains a cycle */
bool dag_cyclic(dag_node *dag);
/** Dump \a dag onto \a f (external binary representation) */
bool dag_dump(dumper *f, dag_node *dag);
#endif