@@ -22,6 +22,7 @@ mod join;
22
22
/// A relation represents a fixed set of key-value pairs. In many places in a
23
23
/// Datalog computation we want to be sure that certain relations are not able
24
24
/// to vary (for example, in antijoins).
25
+ #[ derive( Eq , PartialEq ) ]
25
26
pub struct Relation < Tuple : Ord > {
26
27
/// Wrapped elements in the relation.
27
28
///
@@ -44,8 +45,9 @@ impl<Tuple: Ord> Relation<Tuple> {
44
45
}
45
46
}
46
47
47
- impl < Tuple : Ord > From < Vec < Tuple > > for Relation < Tuple > {
48
- fn from ( mut elements : Vec < Tuple > ) -> Self {
48
+ impl < Tuple : Ord , I : IntoIterator < Item =Tuple > > From < I > for Relation < Tuple > {
49
+ fn from ( iterator : I ) -> Self {
50
+ let mut elements: Vec < Tuple > = iterator. into_iter ( ) . collect ( ) ;
49
51
elements. sort_unstable ( ) ;
50
52
Relation { elements }
51
53
}
@@ -121,6 +123,28 @@ pub struct Variable<Tuple: Ord> {
121
123
// Operator implementations.
122
124
impl < Tuple : Ord > Variable < Tuple > {
123
125
/// Adds tuples that result from joining `input1` and `input2`.
126
+ ///
127
+ /// # Examples
128
+ ///
129
+ /// This example starts a collection with the pairs (x, x+1) and (x+1, x) for x in 0 .. 10.
130
+ /// It then adds pairs (y, z) for which (x, y) and (x, z) are present. Because the initial
131
+ /// pairs are symmetric, this should result in all pairs (x, y) for x and y in 0 .. 11.
132
+ ///
133
+ /// ```
134
+ /// use datafrog::*;
135
+ ///
136
+ /// let mut iteration = Iteration::new();
137
+ /// let variable = iteration.variable::<(usize, usize)>("source");
138
+ /// variable.insert(Relation::from((0 .. 10).map(|x| (x, x + 1))));
139
+ /// variable.insert(Relation::from((0 .. 10).map(|x| (x + 1, x))));
140
+ ///
141
+ /// while iteration.changed() {
142
+ /// variable.from_join(&variable, &variable, |&key, &val1, &val2| (val1, val2));
143
+ /// }
144
+ ///
145
+ /// let result = variable.complete();
146
+ /// assert_eq!(result.len(), 121);
147
+ /// ```
124
148
pub fn from_join < K : Ord , V1 : Ord , V2 : Ord , F : Fn ( & K , & V1 , & V2 ) ->Tuple > (
125
149
& self ,
126
150
input1 : & Variable < ( K , V1 ) > ,
@@ -129,7 +153,30 @@ impl<Tuple: Ord> Variable<Tuple> {
129
153
{
130
154
join:: join_into ( input1, input2, self , logic)
131
155
}
132
- /// Adds tuples that result from antijoining `input1` and `input2`.
156
+ /// Adds tuples from `input1` whose key is not present in `input2`.
157
+ ///
158
+ /// # Examples
159
+ ///
160
+ /// This example starts a collection with the pairs (x, x+1) for x in 0 .. 10. It then
161
+ /// adds any pairs (x+1,x) for which x is not a multiple of three. That excludes four
162
+ /// pairs (for 0, 3, 6, and 9) which should leave us with 16 total pairs.
163
+ ///
164
+ /// ```
165
+ /// use datafrog::*;
166
+ ///
167
+ /// let mut iteration = Iteration::new();
168
+ /// let variable = iteration.variable::<(usize, usize)>("source");
169
+ /// variable.insert(Relation::from((0 .. 10).map(|x| (x, x + 1))));
170
+ ///
171
+ /// let relation = Relation::from((0 .. 10).filter(|x| x % 3 == 0));
172
+ ///
173
+ /// while iteration.changed() {
174
+ /// variable.from_antijoin(&variable, &relation, |&key, &val| (val, key));
175
+ /// }
176
+ ///
177
+ /// let result = variable.complete();
178
+ /// assert_eq!(result.len(), 16);
179
+ /// ```
133
180
pub fn from_antijoin < K : Ord , V : Ord , F : Fn ( & K , & V ) ->Tuple > (
134
181
& self ,
135
182
input1 : & Variable < ( K , V ) > ,
@@ -139,6 +186,36 @@ impl<Tuple: Ord> Variable<Tuple> {
139
186
join:: antijoin_into ( input1, input2, self , logic)
140
187
}
141
188
/// Adds tuples that result from mapping `input`.
189
+ ///
190
+ /// # Examples
191
+ ///
192
+ /// This example starts a collection with the pairs (x, x) for x in 0 .. 10. It then
193
+ /// repeatedly adds any pairs (x, z) for (x, y) in the collection, where z is the Collatz
194
+ /// step for y: it is y/2 if y is even, and 3*y + 1 if y is odd. This produces all of the
195
+ /// pairs (x, y) where x visits y as part of its Collatz journey.
196
+ ///
197
+ /// ```
198
+ /// use datafrog::*;
199
+ ///
200
+ /// let mut iteration = Iteration::new();
201
+ /// let variable = iteration.variable::<(usize, usize)>("source");
202
+ /// variable.insert(Relation::from((0 .. 10).map(|x| (x, x))));
203
+ ///
204
+ /// let relation = Relation::from((0 .. 10).filter(|x| x % 3 == 0));
205
+ ///
206
+ /// while iteration.changed() {
207
+ /// variable.from_map(&variable, |&(key, val)|
208
+ /// if val % 2 == 0 {
209
+ /// (key, val/2)
210
+ /// }
211
+ /// else {
212
+ /// (key, 3*val + 1)
213
+ /// });
214
+ /// }
215
+ ///
216
+ /// let result = variable.complete();
217
+ /// assert_eq!(result.len(), 74);
218
+ /// ```
142
219
pub fn from_map < T2 : Ord , F : Fn ( & T2 ) ->Tuple > ( & self , input : & Variable < T2 > , logic : F ) {
143
220
map:: map_into ( input, self , logic)
144
221
}
@@ -218,12 +295,12 @@ impl<Tuple: Ord> VariableTrait for Variable<Tuple> {
218
295
* self . recent . borrow_mut ( ) = to_add;
219
296
}
220
297
221
- let mut total = 0 ;
222
- for tuple in self . tuples . borrow ( ) . iter ( ) {
223
- total += tuple. len ( ) ;
224
- }
298
+ // let mut total = 0;
299
+ // for tuple in self.tuples.borrow().iter() {
300
+ // total += tuple.len();
301
+ // }
225
302
226
- println ! ( "Variable\t {}\t {}\t {}" , self . name, total, self . recent. borrow( ) . len( ) ) ;
303
+ // println!("Variable\t{}\t{}\t{}", self.name, total, self.recent.borrow().len());
227
304
228
305
!self . recent . borrow ( ) . is_empty ( )
229
306
}
0 commit comments