with debug
[prop.git] / prop-src / graphops.pcc
blob64fb41b80f37fa8fcddc6be881a1701f22d25e59
1 ///////////////////////////////////////////////////////////////////////////////
2 //
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.
6 //
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
29
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
44        );
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
52        ); 
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
60        ); 
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
73        );
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(), 
85          edge_name, edge_name
86        );
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()
93        );
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
139        );
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
147        );
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);
168    C.pr("%^if (z)"
169         "%^{%+");
171    // f(x) was defined
173    if (ops & RANgop) 
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;");
179       C.pr("%^}");
180    }
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);
191    C.pr("%-%^}");
193    // f(x) := y
195    C.pr("%^x->%s.image = y;", edge_name);
197    if (ops & RANgop) 
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;");
203       C.pr("%^}");
204    }
206    // The graph has changed
208    C.pr("%^return true;"
209         "%-%^}");
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
216        );