1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the low level graph operators.
4 // We assume that these functions are called only if the appropriate
5 // representations are defined.
7 ///////////////////////////////////////////////////////////////////////////////
9 #include "graphtype.ph"
10 #include "graphedges.ph"
12 ///////////////////////////////////////////////////////////////////////////////
14 // Return the domain set as a doubly linked list
16 ///////////////////////////////////////////////////////////////////////////////
17 void EdgeDef::gen_dom (CodeGen& C) // dom f
19 C.pr("%^%s_set domain() const { return %s_set(domset); }",
20 domain_type->name(), domain_type->name());
23 ///////////////////////////////////////////////////////////////////////////////
25 // Return the range set as a doubly linked list
27 ///////////////////////////////////////////////////////////////////////////////
28 void EdgeDef::gen_ran (CodeGen& C) // ran f
30 C.pr("%^%s_set range() const { return %s_set(ranset); }",
31 range_type->name(), range_type->name());
35 ///////////////////////////////////////////////////////////////////////////////
37 // Test if an element is defined in the domain
39 ///////////////////////////////////////////////////////////////////////////////
40 void EdgeDef::gen_in_dom (CodeGen& C) // x in dom f
41 { C.pr("%^Bool domain_has (%s x) const"
42 "%^ { return x->%s.dom_link.non_nil(); }",
43 domain_type->name(), edge_name
47 void MapEdge::gen_in_dom (CodeGen& C) // x in dom f
48 { if (ops & DOMgop) { Super::gen_in_dom(C); return; }
49 C.pr("%^Bool domain_has (%s x) const"
50 "%^ { return x->%s.image != 0; }",
51 domain_type->name(), edge_name
55 void MultiMapEdge::gen_in_dom (CodeGen& C) // x in dom f
56 { if (ops & DOMgop) { Super::gen_in_dom(C); return; }
57 C.pr("%^Bool domain_has (%s x) const"
58 "%^ { return ! x->%s.image.is_empty(); }",
59 domain_type->name(), edge_name
63 ///////////////////////////////////////////////////////////////////////////////
65 // Test if an element is defined in the range
67 ///////////////////////////////////////////////////////////////////////////////
68 void EdgeDef::gen_in_ran (CodeGen& C) // x in ran f
70 C.pr("%^Bool range_has (%s x) const"
71 "%^ { return x->%s.coimage != 0; }",
72 range_type->name(), edge_name
76 ///////////////////////////////////////////////////////////////////////////////
78 // Test if a pair is defined
80 ///////////////////////////////////////////////////////////////////////////////
81 void MapEdge::gen_in (CodeGen& C) // x in f
82 { C.pr("%^Bool has (%s x, %s y) const"
83 "%^ { return x->%s.image && x->%s.image == y; }",
84 domain_type->name(), range_type->name(),
89 void MultiMapEdge::gen_in (CodeGen& C) // x in f
90 { C.pr("%^Bool has (%s x, %s y) const"
91 "%^ { return false; }",
92 domain_type->name(), range_type->name()
96 ///////////////////////////////////////////////////////////////////////////////
98 // Return the cardinality of a relation
100 ///////////////////////////////////////////////////////////////////////////////
101 void EdgeDef::gen_size (CodeGen& C) // # f
103 C.pr("%^int size () const { return count; }");
106 ///////////////////////////////////////////////////////////////////////////////
108 // Return the cardinality of the domain
110 ///////////////////////////////////////////////////////////////////////////////
111 void EdgeDef::gen_dom_size (CodeGen& C) // # dom f
113 C.pr("%^int domain_size () const { return dom_count; }");
116 ///////////////////////////////////////////////////////////////////////////////
118 // Return the cardinality of the range
120 ///////////////////////////////////////////////////////////////////////////////
121 void EdgeDef::gen_ran_size (CodeGen& C) // # ran f
123 C.pr("%^int range_size () const { return ran_count; }");
126 ///////////////////////////////////////////////////////////////////////////////
128 // Return the image or image set
130 ///////////////////////////////////////////////////////////////////////////////
131 void EdgeDef::gen_image (CodeGen& C) // f(x) or f{x}
132 { bug("%Limage operation is undefined for edge %s", edge_name);
135 void MapEdge::gen_image (CodeGen& C) // f(x)
136 { C.pr("%^%s operator () (%s x) const"
137 "%^ { return x->%s.image; }",
138 range_type->name(), domain_type->name(), edge_name
142 void MultiMapEdge::gen_image (CodeGen& C) // f{x}
143 { C.pr("%^%s_set operator () (%s x) const"
144 "%^ { return %s_set(x->%s.image); }",
145 range_type->name(), domain_type->name(),
146 range_type->name(), edge_name
150 ///////////////////////////////////////////////////////////////////////////////
152 // Update the image or image set
154 ///////////////////////////////////////////////////////////////////////////////
155 void EdgeDef::gen_update_image (CodeGen& C) // f(x) or f{x}
156 { bug("%Limage operation is undefined for edge %s", edge_name);
159 void MapEdge::gen_update_image (CodeGen& C) // f(x)
160 { C.pr("%^Bool update(%s x, %s y)%^{%+",
161 domain_type->name(), range_type->name());
163 // If the edge is already there do nothing
164 C.pr("%^%s z = x->%s.image;"
165 "%^if (z == y) return false;",
166 range_type->name(), edge_name);
174 { // Update the range set; remove the old element
175 C.pr("%^if(--z->%s.ran_count == 0)"
176 "%^{ z->%s.ran_link.unlink();",
177 edge_name, edge_name);
178 if (ops & RANSIZEgop) C.pr("%^ --ran_count;");
182 C.pr("%-%^}%^else%^{%+");
184 // f(x) was undefined
186 if (ops & SIZEgop) C.pr("%^++count;"); // a new edge is added
187 if (ops & DOMSIZEgop) C.pr("%^++dom_count;"); // a new domain element
188 if (ops & DOMgop) // link the new element
189 C.pr("%^domset.link(x->%s.dom_link);", edge_name);
195 C.pr("%^x->%s.image = y;", edge_name);
198 { // Update the new range set
199 C.pr("%^if (++y->%s.ran_count == 1)"
200 "%^{ ranset.link(y->%s.ran_link);",
201 edge_name, edge_name);
202 if (ops & RANSIZEgop) C.pr("%^ ++ran_count;");
206 // The graph has changed
208 C.pr("%^return true;"
212 void MultiMapEdge::gen_update_image (CodeGen& C) // f(x)
213 { C.pr("%^Bool update(%s x, const %s_set& y)"
214 "%^ { x->%s.image = y.link; }",
215 domain_type->name(), range_type->name(), edge_name