ignore .lib and .exe
[prop.git] / prop-src / graphrep.pcc
blobd26b4dd7c2472addb196ac10da65044f6d757b4e
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // This file implements data structure mapping for graph nodes and edges.
4 //
5 ///////////////////////////////////////////////////////////////////////////////
6 #include "graphedges.ph"
8 ///////////////////////////////////////////////////////////////////////////////
9 //
10 //  Instantiate the nodes and edges datatypes
12 ///////////////////////////////////////////////////////////////////////////////
13 instantiate datatype List<NodeDef *>, List<EdgeDef *>;
15 ///////////////////////////////////////////////////////////////////////////////
17 //  Constructors for all edge classes
19 ///////////////////////////////////////////////////////////////////////////////
20 MapEdge::MapEdge(GraphTypeDef * G,
21                  Id id, NodeDef* a, NodeDef* b, GraphIndexing i, LabTys attribs)
22   : EdgeDef(G,id,a,b,i,attribs) {} 
24 MultiMapEdge::MultiMapEdge
25     (GraphTypeDef * G,
26      Id id, NodeDef* a, NodeDef* b, GraphIndexing i, LabTys attribs)
27   : EdgeDef(G,id,a,b,i,attribs) {} 
29 BijectionEdge::BijectionEdge
30     (GraphTypeDef * G,
31      Id id, NodeDef* a, NodeDef* b, GraphIndexing i, LabTys attribs)
32   : MapEdge(G,id,a,b,i,attribs) {} 
34 EquivRelationEdge::EquivRelationEdge
35     (GraphTypeDef * G,
36      Id id, NodeDef* a, NodeDef* b, GraphIndexing i, LabTys attribs)
37   : MapEdge(G,id,a,b,i,attribs) {} 
39 ///////////////////////////////////////////////////////////////////////////////
41 //  Method to computing the proper representation for a node 
43 ///////////////////////////////////////////////////////////////////////////////
44 void NodeDef::choose_representation()
48 ///////////////////////////////////////////////////////////////////////////////
50 //  Methods to computing the proper representation for an edge 
52 ///////////////////////////////////////////////////////////////////////////////
53 void EdgeDef::choose_representation()
54 {  // If we have f(x) or f{x} then we also have 'x in dom f' for free
55    if (ops & (IMAGEgop | IMAGESETgop))
56       ops |= INDOMgop; 
57    if (ops & INDOMgop) 
58       ops |= INgop; // x in f
61 void MapEdge::choose_representation()
62 {  ops |= IMAGEgop;       // f(x)
63    ops |= DOMgop;         // dom f
64    ops |= RANgop;         // ran f
65    ops |= DOMSIZEgop;     // #dom f
66    ops |= RANSIZEgop;     // #ran f
67    ops |= UPDATEIMAGEgop; // f(x) := y
68    ops |= SIZEgop;        // # f
69    Super::choose_representation();
72 void MultiMapEdge::choose_representation()
73 {  ops |= IMAGESETgop;    // f{x}
74    ops |= DOMgop;         // dom f
75    ops |= DOMSIZEgop;     // #dom f
76    ops |= RANSIZEgop;     // #ran f
77    ops |= UPDATEIMAGEgop; // f{x} with := y
78    ops |= SIZEgop;        // # f
79    Super::choose_representation();
82 void BijectionEdge::choose_representation()
83 {  
84    Super::choose_representation();
87 void EquivRelationEdge::choose_representation()
88 {  
89    Super::choose_representation();
92 ///////////////////////////////////////////////////////////////////////////////
94 //  Generic method to generate forward declarations for a node object
96 ///////////////////////////////////////////////////////////////////////////////
97 void NodeDef::generate_forward_decls (CodeGen& C)
99    C.pr("%^class %s_%s_node;", graph()->class_name, node_name);
102 ///////////////////////////////////////////////////////////////////////////////
104 //  Generic method to generate representation for a node object class.
106 ///////////////////////////////////////////////////////////////////////////////
107 void NodeDef::generate_representation (CodeGen& C)
108 {  C.pr("\n"
109         "%^%/"
110         "%^//"
111         "%^//  Representation of node %s::%s(%T)"
112         "%^//"
113         "%^%/",
114         graph()->class_name, node_name, node_type
115        );
117    C.pr("%^class %s_%s_node {%+"
118            "%^// no copy constructor or assignment"
119            "%^%s_%s_node(const %s_%s_node&);"
120            "%^void operator = (const %s_%s_node&);"
121            "%^%T the_label;"
122         "%-%^public:%+"
123           "%^%T label() const { return the_label; }"
124           "%^operator %T () const { return the_label; }"
125           "%^friend class %s;",
126         graph()->class_name, node_name,
127         graph()->class_name, node_name, graph()->class_name, node_name,
128         graph()->class_name, node_name, 
129         node_type, node_type, node_type, graph()->class_name
130        );
132    for_each (EdgeDef *, e, graph()->edge_defs)
133    {  e->generate_node_representation(C,this);
134    }
136    C.pr("%-%^public:%+"
137            "%^%s_%s_node();"
138            "%^~%s_%s_node();"
139         "%-%^};",
140         graph()->class_name, node_name,
141         graph()->class_name, node_name
142        );
144    C.pr("\n\n");
147 ///////////////////////////////////////////////////////////////////////////////
149 //  Generic method to generate interface for a node object
151 ///////////////////////////////////////////////////////////////////////////////
152 void NodeDef::generate_interface (CodeGen& C)
153 {  C.pr("%-%^public:%+"
154         "%^%/"
155         "%^//"
156         "%^// Interface to node %s(%T)"
157         "%^//"
158         "%^%/",
159         node_name, node_type
160    );
162    if (node_type == NOty)
163    { 
164       C.pr("%^// Create a new node; the new node is unique."
165            "%^// The new node is now attached to the graph."
166            "%^virtual %s create_%s();",
167            node_name, node_name
168           );
169    } else
170    {  
171       C.pr("%-%^protected:%+"
172            "%^// HashTable< %T, %s, %s< %T >, %s< %T > > %s_table;"
173            "%-%^public:%+",
174            node_type, node_name, hash_fun, node_type, 
175            eq_fun, node_type, node_name
176           );
177    
178       C.pr("%^// Create a new node, or lookup an existing node."
179            "%^// The node is now attached to the graph."
180            "%^virtual %s create_%s(%T);"
181            "%^\n"
182            "%^// Lookup a node by its label." 
183            "%^// Returns nil if no such node exists."
184            "%^%s lookup_%s(%T) const;"
185            "%^\n"
186            "%^// Does a node of a certain label exists?"
187            "%^Bool has_%s(%T l) const { return lookup_%s(l) != 0; }"
188            "%^\n"
189            "%^// Insert a new node into the graph by label."
190            "%^// A no-op if the graph with the label already exists"
191            "%^%s insert_%s(%T l) { return create_%s(l); }"
192            "%^\n"
193            "%^// Remove a node by label."
194            "%^// Returns true if the graph is changed."
195            "%^Bool remove_%s(%T l) { return remove(lookup_%s(l)); }",
196            node_name, node_name, node_type,
197            node_name, node_name, node_type,
198            node_name, node_type, node_name,
199            node_name, node_name, node_type, node_name,
200            node_name, node_type, node_name
201          );
202    }
204    C.pr("%^\n"
205         "%^// Insert a node into the graph."
206         "%^// Returns true if the graph is changed."
207         "%^virtual Bool insert(%s);" 
208         "%^\n"
209         "%^// Remove a node from the graph."
210         "%^// The node is destroyed."
211         "%^// Returns true if the graph is changed."
212         "%^virtual Bool remove(%s);",
213         node_name, node_name
214        );
217 ///////////////////////////////////////////////////////////////////////////////
219 //  Generic method to generate the implementation for a node object
221 ///////////////////////////////////////////////////////////////////////////////
222 void NodeDef::generate_implementation (CodeGen& C)
223 {  C.pr("%^%/"
224         "%^// Implementation of node %s::%s(%T)"
225         "%^%/",
226         graph()->class_name, node_name, node_type
227        );
230 ///////////////////////////////////////////////////////////////////////////////
232 //  Generic method to generate representation for an edge within a node
234 ///////////////////////////////////////////////////////////////////////////////
235 void EdgeDef::generate_node_representation (CodeGen& C, NodeDef * n)
236 {  if (n != domain_type && n != range_type) return;
237    C.pr("%^struct {%+");
238    if (n == domain_type) generate_dom_rep(C);
239    if (n == range_type)  generate_ran_rep(C);
240    C.pr("%-%^} %s;",edge_name);
243 ///////////////////////////////////////////////////////////////////////////////
245 //  Generic method to generate representation for an edge within the graph
247 ///////////////////////////////////////////////////////////////////////////////
248 void EdgeDef::generate_edge_representation (CodeGen& C)
249 {  generate_edge_rep(C);
252 ///////////////////////////////////////////////////////////////////////////////
254 //  Generic method to generate representation for an edge within the graph
256 ///////////////////////////////////////////////////////////////////////////////
257 void EdgeDef::generate_edge_rep (CodeGen& C)
258 {  if (ops & SIZEgop)    C.pr("%^int count;              // number of edges ");
259    if (ops & DOMgop)     C.pr("%^GraphType::Link domset; // the domain");
260    if (ops & DOMSIZEgop) C.pr("%^int dom_count;          // size of domain");
261    if (ops & RANgop)     C.pr("%^GraphType::Link ranset; // the range");
262    if (ops & RANSIZEgop) C.pr("%^int ran_count;          // size of range");
265 ///////////////////////////////////////////////////////////////////////////////
267 //  Methods to compute the representation
269 ///////////////////////////////////////////////////////////////////////////////
270 void EdgeDef::generate_dom_rep(CodeGen& C)
271 {  
272    if (ops & DOMgop) C.pr("%^GraphType::Link dom_link;");
275 void EdgeDef::generate_ran_rep(CodeGen& C)
276 {  
277    if (ops & RANgop) 
278       C.pr("%^GraphType::Link ran_link;"
279            "%^int ran_count;");
282 void MapEdge::generate_dom_rep(CodeGen& C)
283 {  Super::generate_dom_rep(C);
284    if (ops & IMAGEgop)
285       C.pr("%^%s_%s_node * image;", graph->class_name, range_type->name());
288 void MapEdge::generate_ran_rep(CodeGen& C)
289 {  Super::generate_ran_rep(C);
292 void MultiMapEdge::generate_dom_rep(CodeGen& C)
293 {  Super::generate_dom_rep(C);
294    if (ops & IMAGESETgop) C.pr("%^GraphType::Link image;");
297 void MultiMapEdge::generate_ran_rep(CodeGen& C)
298 {  Super::generate_ran_rep(C);
301 void BijectionEdge::generate_dom_rep(CodeGen& C)
302 {  Super::generate_dom_rep(C);
305 void BijectionEdge::generate_ran_rep(CodeGen& C)
306 {  Super::generate_ran_rep(C);
309 void EquivRelationEdge::generate_dom_rep(CodeGen& C)
310 {  Super::generate_dom_rep(C);
313 void EquivRelationEdge::generate_ran_rep(CodeGen& C)
314 {  Super::generate_ran_rep(C);
317 ///////////////////////////////////////////////////////////////////////////////
319 //  Generic methods to generate the interface of an edge 
321 ///////////////////////////////////////////////////////////////////////////////
322 void EdgeDef::generate_interface (CodeGen& C)
324    if (domain_type == 0 || range_type == 0) return;
326    // 
327    // Encapsulate all methods to manipulate this edge into an edge record
328    //
329    C.pr("%^class %s_record {"
330         "%^protected:%+"
331         "%^friend class %s;", 
332         edge_name, graph->class_name);
333    generate_edge_representation(C);  // how to represent this edge
334    C.pr("%-%^public:%+");
335    generate_interf(C);               // the methods
336    C.pr("%-%^} %s;"
337         "%^", edge_name);
340 ///////////////////////////////////////////////////////////////////////////////
342 //  Methods to generate the interface of an edge 
344 ///////////////////////////////////////////////////////////////////////////////
345 void EdgeDef::generate_interf (CodeGen& C)
347    if (ops & DOMgop)     gen_dom(C);          // dom f
348    if (ops & RANgop)     gen_ran(C);          // ran f
349    if (ops & INDOMgop)   gen_in_dom(C);       // x in dom f
350    if (ops & INRANgop)   gen_in_ran(C);       // x in ran f
351    if (ops & INgop)      gen_in(C);           // x in f
352    if (ops & SIZEgop)    gen_size(C);         // size of relation
353    if (ops & DOMSIZEgop) gen_dom_size(C);     // size of domain
354    if (ops & RANSIZEgop) gen_ran_size(C);     // size of range
355    if (ops & (IMAGEgop | IMAGESETgop)) gen_image(C); // f(x) or f{x}
356    if (ops & UPDATEIMAGEgop) gen_update_image(C); // f(x) := y or f{x} with := y
359 void MapEdge::generate_interf(CodeGen& C) 
360 {  Super::generate_interf(C);
363 void MultiMapEdge::generate_interf(CodeGen& C) 
364 {  Super::generate_interf(C);
367 void BijectionEdge::generate_interf(CodeGen& C) 
368 {  Super::generate_interf(C);
371 void EquivRelationEdge::generate_interf(CodeGen& C) 
372 {  Super::generate_interf(C);
375 ///////////////////////////////////////////////////////////////////////////////
377 //  Generic methods to generate the implementation of an edge 
379 ///////////////////////////////////////////////////////////////////////////////
380 void EdgeDef::generate_implementation (CodeGen& C)
382    generate_impl(C);
385 ///////////////////////////////////////////////////////////////////////////////
387 //  Methods to generate the implementation 
389 ///////////////////////////////////////////////////////////////////////////////
390 void EdgeDef::generate_impl(CodeGen& C) 
391 {  
394 void MapEdge::generate_impl(CodeGen& C) 
395 {  Super::generate_impl(C);
398 void MultiMapEdge::generate_impl(CodeGen& C) 
399 {  Super::generate_impl(C);
402 void BijectionEdge::generate_impl(CodeGen& C) 
403 {  Super::generate_impl(C);
406 void EquivRelationEdge::generate_impl(CodeGen& C) 
407 {  Super::generate_impl(C);