porolog 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,15 +53,14 @@ describe 'Object' do
53
53
 
54
54
  describe '#/' do
55
55
 
56
- it 'should create a n Array with a Tail' do
57
- skip 'until Variable added'
56
+ it 'should create an n Array with a Tail' do
58
57
  assert_Array_with_Tail object1 / :T, [object1], '*:T'
59
58
  assert_Array_with_Tail [object2] / :T, [object2], '*:T'
60
- assert_Array_with_Tail object2.tail(:T), [object2], '*:T'
59
+ #assert_Array_with_Tail object2.tail(:T), [object2], '*:T'
61
60
  assert_Array_with_Tail object3 / :T, [object3], '*:T'
62
61
  assert_Array_with_Tail object4 / :T, [object4], '*:T'
63
62
  assert_Array_with_Tail [object5] / :T, [object5], '*:T'
64
- assert_Array_with_Tail object2.tail(:T), [object5], '*:T'
63
+ #assert_Array_with_Tail object5.tail(:T), [object5], '*:T'
65
64
  end
66
65
 
67
66
  end
@@ -115,7 +114,6 @@ describe 'Symbol' do
115
114
  describe '#/' do
116
115
 
117
116
  it 'should create a HeadTail' do
118
- skip 'until Variable added'
119
117
  assert_Array_with_Tail symbol1 / :T, [symbol1], '*:T'
120
118
  assert_Array_with_Tail symbol2 / :T, [symbol2], '*:T'
121
119
  assert_Array_with_Tail symbol3 / :T, [symbol3], '*:T'
@@ -136,8 +134,21 @@ describe 'Array' do
136
134
 
137
135
  describe '#/' do
138
136
 
137
+ it 'creates an Array using the slash notation with Arrays' do
138
+ head_tail = [1] / [2,3,4,5]
139
+
140
+ assert_equal [1,2,3,4,5], head_tail
141
+ end
142
+
143
+ it 'should combine a head Array and a tail Array when they have no variables' do
144
+ assert_equal [1,2,3,4,5,6], [1,2,3] / [4,5,6]
145
+ end
146
+
147
+ it 'should combine an embedded head Array and an embedded tail Array when they have no variables' do
148
+ assert_equal [1,2,3,4,5,6,7,8,9], [1,2,3] / [4,5,6] / [7,8,9]
149
+ end
150
+
139
151
  it 'should create a HeadTail' do
140
- skip 'until Variable added'
141
152
  assert_Array_with_Tail array1 / :T, array1, '*:T'
142
153
  assert_Array_with_Tail array2 / :T, array2, '*:T'
143
154
  assert_Array_with_Tail array3 / :T, array3, '*:T'
@@ -149,7 +160,6 @@ describe 'Array' do
149
160
  describe '#variables' do
150
161
 
151
162
  it 'should return an array of the embedded Symbols' do
152
- skip 'until Tail added'
153
163
  assert_equal [:A, :B, :C], array1.variables
154
164
  assert_equal [], array2.variables
155
165
  assert_equal [], array3.variables
@@ -161,7 +171,6 @@ describe 'Array' do
161
171
  describe '#value' do
162
172
 
163
173
  it 'should return simple Arrays as is' do
164
- skip 'until Tail added'
165
174
  assert_equal [1, 2, :A, 4, [:B, 6, 7, :C], 9], array1.value
166
175
  assert_equal [], array2.value
167
176
  assert_equal [UNKNOWN_TAIL], array3.value
@@ -169,14 +178,12 @@ describe 'Array' do
169
178
  end
170
179
 
171
180
  it 'should expand Tails that are an Array' do
172
- skip 'until Tail added'
173
181
  array = [1,2,3,Tail.new([7,8,9])]
174
182
 
175
183
  assert_equal [1,2,3,7,8,9], array.value
176
184
  end
177
185
 
178
186
  it 'should return the value of instantiated variables in a Tail' do
179
- skip 'until Variable added'
180
187
  goal = new_goal :tailor, :h, :t
181
188
  array = goal.variablise([:h, :b] / :t)
182
189
  goal.instantiate :h, [1,2,3]
@@ -185,12 +192,18 @@ describe 'Array' do
185
192
  assert_equal [goal.value([1,2,3]),goal.variable(:b), goal.value(7), goal.value(8), goal.value(9)], array.value
186
193
  end
187
194
 
195
+ it 'should return the value of instantiated variables in a Tail' do
196
+ goal = new_goal :taylor, :head, :tail
197
+ array = [Tail.new(goal.value([5,6,7,8]))]
198
+
199
+ assert_equal [5,6,7,8], array.value
200
+ end
201
+
188
202
  end
189
203
 
190
204
  describe '#type' do
191
205
 
192
206
  it 'should return :variable for symbols' do
193
- skip 'until Tail added'
194
207
  assert_equal :array, array1.type
195
208
  assert_equal :array, array2.type
196
209
  assert_equal :array, array3.type
@@ -202,7 +215,6 @@ describe 'Array' do
202
215
  describe '#head' do
203
216
 
204
217
  it 'should return the first element when no headsize is provided' do
205
- skip 'until Tail added'
206
218
  assert_equal 1, array1.head
207
219
  assert_nil array2.head
208
220
  assert_nil array3.head
@@ -210,7 +222,6 @@ describe 'Array' do
210
222
  end
211
223
 
212
224
  it 'should return the first headsize elements' do
213
- skip 'until Tail added'
214
225
  assert_equal [1, 2], array1.head(2)
215
226
  assert_equal [], array2.head(2)
216
227
  assert_equal [UNKNOWN_TAIL], array3.head(2)
@@ -218,7 +229,6 @@ describe 'Array' do
218
229
  end
219
230
 
220
231
  it 'should return an extended head if the tail is uninstantiated' do
221
- skip 'until Tail added'
222
232
  assert_equal [1, 2, :A, 4, [:B, 6, 7, :C], 9], array1.head(9)
223
233
  assert_equal [], array2.head(9)
224
234
  assert_equal [UNKNOWN_TAIL], array3.head(9)
@@ -230,7 +240,6 @@ describe 'Array' do
230
240
  describe '#tail' do
231
241
 
232
242
  it 'should return the tail after the first element when no headsize is provided' do
233
- skip 'until Tail added'
234
243
  assert_equal [2, :A, 4, [:B, 6, 7, :C], 9], array1.tail
235
244
  assert_equal [], array2.tail
236
245
  assert_equal [UNKNOWN_TAIL], array3.tail
@@ -238,7 +247,6 @@ describe 'Array' do
238
247
  end
239
248
 
240
249
  it 'should return the tail after the first headsize elements' do
241
- skip 'until Tail added'
242
250
  assert_equal [:A, 4, [:B, 6, 7, :C], 9], array1.tail(2)
243
251
  assert_equal [], array2.tail(2)
244
252
  assert_equal [UNKNOWN_TAIL], array3.tail(2)
@@ -246,7 +254,6 @@ describe 'Array' do
246
254
  end
247
255
 
248
256
  it 'should return an extended tail if the tail is uninstantiated' do
249
- skip 'until Tail added'
250
257
  assert_equal [], array1.tail(9)
251
258
  assert_equal [], array2.tail(9)
252
259
  assert_equal [UNKNOWN_TAIL], array3.tail(9)
@@ -16,6 +16,10 @@ describe 'Porolog' do
16
16
 
17
17
  describe 'Goal' do
18
18
 
19
+ let(:pred) { Predicate.new :p }
20
+ let(:args) { pred.(:x,:y) }
21
+ let(:goal) { Goal.new args }
22
+
19
23
  describe '.reset' do
20
24
 
21
25
  it 'should clear all goals' do
@@ -45,10 +49,6 @@ describe 'Porolog' do
45
49
  Goal.reset
46
50
  end
47
51
 
48
- it 'should clear the goal cache' do
49
- # TECH-CREDIT: Probably not going to use a cache; we'll see ...
50
- end
51
-
52
52
  end
53
53
 
54
54
  describe '.goals' do
@@ -58,17 +58,14 @@ describe 'Porolog' do
58
58
 
59
59
  goal1 = new_goal :predicate1, :a
60
60
 
61
- assert_equal 1, Goal.goals.size
62
61
  assert_equal [goal1], Goal.goals
63
62
 
64
63
  goal2 = new_goal :predicate2, :a, :b
65
64
 
66
- assert_equal 2, Goal.goals.size
67
65
  assert_equal [goal1,goal2], Goal.goals
68
66
 
69
67
  goal3 = new_goal :predicate3, :a, :b, :c
70
68
 
71
- assert_equal 3, Goal.goals.size
72
69
  assert_equal [goal1,goal2,goal3], Goal.goals
73
70
  end
74
71
 
@@ -87,9 +84,6 @@ describe 'Porolog' do
87
84
  describe '#initialize' do
88
85
 
89
86
  it 'should initialize calling_goal' do
90
- pred = Predicate.new :p
91
- args = pred.(:x,:y)
92
-
93
87
  goal1 = Goal.new args
94
88
  goal2 = Goal.new args, goal1
95
89
 
@@ -101,40 +95,112 @@ describe 'Porolog' do
101
95
  end
102
96
 
103
97
  it 'should initialize arguments' do
104
- pred = Predicate.new :p
105
- args = pred.(:x,:y)
106
-
107
98
  goal = Goal.new args, nil
108
99
 
109
- assert_equal args, goal.arguments
100
+ assert_equal goal.variablise(args), goal.arguments
110
101
  end
111
102
 
112
103
  it 'should initialize terminate' do
113
- pred = Predicate.new :p
114
- args = pred.(:x,:y)
115
-
116
104
  goal = Goal.new args, nil
117
105
 
118
- assert_equal false, goal.terminate
106
+ assert_equal false, goal.terminated?
119
107
  end
120
108
 
121
109
  it 'should initialize variables' do
122
- pred = Predicate.new :p
123
- args = pred.(:x,:y)
124
-
125
110
  goal = Goal.new args, nil
126
111
 
127
- assert_Goal_variables goal, {}, ''
112
+ assert_Goal_variables goal, { x: nil, y: nil }, [
113
+ 'Goal1.:x',
114
+ 'Goal1.:y',
115
+ ].join("\n")
128
116
  end
129
117
 
130
118
  it 'should register the goal as undeleted' do
131
- pred = Predicate.new :p
132
- args = pred.(:x,:y)
119
+ goal1 = Goal.new args, nil
120
+ goal2 = Goal.new args, goal1
133
121
 
122
+ assert_equal [goal1,goal2], Goal.goals
123
+ end
124
+
125
+ end
126
+
127
+ describe '#myid' do
128
+
129
+ it 'should return the pretty id of the goal' do
134
130
  goal1 = Goal.new args, nil
135
131
  goal2 = Goal.new args, goal1
136
132
 
137
- assert_equal [goal1,goal2], Goal.goals
133
+ assert_equal 'Goal1', goal1.myid
134
+ assert_equal 'Goal2', goal2.myid
135
+ end
136
+
137
+ end
138
+
139
+ describe '#ancestors' do
140
+
141
+ it 'should return an Array of the parent goals' do
142
+ goal1 = Goal.new args
143
+ goal2 = Goal.new args, goal1
144
+ goal3 = Goal.new args, goal2
145
+ goal4 = Goal.new args, goal3
146
+
147
+ assert_equal [goal1], goal1.ancestors
148
+ assert_equal [goal1, goal2], goal2.ancestors
149
+ assert_equal [goal1, goal2, goal3], goal3.ancestors
150
+ assert_equal [goal1, goal2, goal3, goal4], goal4.ancestors
151
+ end
152
+
153
+ end
154
+
155
+ describe '#ancestry' do
156
+
157
+ it 'should return an Array of the parent goals' do
158
+ goal1 = Goal.new args
159
+ goal2 = Goal.new args, goal1
160
+ goal3 = Goal.new args, goal2
161
+ goal4 = Goal.new args, goal3
162
+
163
+ ancestors = [
164
+ 'Goal1 -- Solve p(:x,:y) {:x=>nil, :y=>nil}',
165
+ ' Goal2 -- Solve p(:x,:y) {:x=>nil, :y=>nil}',
166
+ ' Goal3 -- Solve p(:x,:y) {:x=>nil, :y=>nil}',
167
+ ' Goal4 -- Solve p(:x,:y) {:x=>nil, :y=>nil}',
168
+ ]
169
+
170
+ assert_equal ancestors[0...1].join("\n"), goal1.ancestry
171
+ assert_equal ancestors[0...2].join("\n"), goal2.ancestry
172
+ assert_equal ancestors[0...3].join("\n"), goal3.ancestry
173
+ assert_equal ancestors[0...4].join("\n"), goal4.ancestry
174
+ end
175
+
176
+ end
177
+
178
+ describe '#inspect' do
179
+
180
+ it 'should show a description of the goal' do
181
+ goal1 = Goal.new args
182
+ goal2 = Goal.new pred.(1,:b,'word'), goal1
183
+ goal3 = Goal.new args, goal2
184
+ goal4 = Goal.new args, goal3
185
+
186
+ assert_equal 'Goal1 -- Solve p(:x,:y)', goal1.inspect
187
+ assert_equal 'Goal2 -- Solve p(1,:b,"word")', goal2.inspect
188
+ assert_equal 'Goal3 -- Solve p(:x,:y)', goal3.inspect
189
+ assert_equal 'Goal4 -- Solve p(:x,:y)', goal4.inspect
190
+ end
191
+
192
+ end
193
+
194
+ describe '#delete!' do
195
+
196
+ it 'should delete the goal' do
197
+ goal1 = Goal.new args
198
+ goal2 = Goal.new pred.(1,:b,'word'), goal1
199
+ goal3 = Goal.new args, goal2
200
+ goal4 = Goal.new args, goal3
201
+
202
+ assert goal2.delete!, 'goal should delete'
203
+ assert_equal [goal1, goal3, goal4], Goal.goals
138
204
  end
139
205
 
140
206
  end
@@ -157,9 +223,6 @@ describe 'Porolog' do
157
223
  describe '#deleted?' do
158
224
 
159
225
  it 'should return the deleted state of a goal' do
160
- pred = Predicate.new :p
161
- args = pred.(:x,:y)
162
-
163
226
  goal = Goal.new args
164
227
 
165
228
  refute goal.deleted?, 'goal should not be deleted'
@@ -170,9 +233,6 @@ describe 'Porolog' do
170
233
  end
171
234
 
172
235
  it 'should memoize the deleted state of a goal' do
173
- pred = Predicate.new :p
174
- args = pred.(:x,:y)
175
-
176
236
  goal = Goal.new args
177
237
 
178
238
  check_deleted_spy = Spy.on(goal, :check_deleted).and_call_through
@@ -197,11 +257,6 @@ describe 'Porolog' do
197
257
  describe '#check_deleted' do
198
258
 
199
259
  it 'should return false when the goal is not deleted and keep variables intact' do
200
- skip 'until Variable added'
201
-
202
- pred = Predicate.new :p
203
- args = pred.(:x,:y)
204
-
205
260
  goal = Goal.new args
206
261
  goal.variable(:x)
207
262
  goal.variable(:y)
@@ -209,17 +264,12 @@ describe 'Porolog' do
209
264
 
210
265
  variable_remove_spy = Spy.on_instance_method(Variable, :remove)
211
266
 
212
- refute goal.check_deleted
267
+ refute goal.check_deleted, 'goal should not be deleted'
213
268
 
214
269
  assert_equal 0, variable_remove_spy.calls.size
215
270
  end
216
271
 
217
272
  it 'should return true when the goal is deleted and remove all variables' do
218
- skip 'until Variable added'
219
-
220
- pred = Predicate.new :p
221
- args = pred.(:x,:y)
222
-
223
273
  goal = Goal.new args
224
274
  goal.variable(:x)
225
275
  goal.variable(:y)
@@ -229,21 +279,83 @@ describe 'Porolog' do
229
279
 
230
280
  Goal.reset
231
281
 
232
- assert goal.check_deleted
282
+ assert goal.check_deleted, 'goal should be deleted'
233
283
 
234
284
  assert_equal 3, variable_remove_spy.calls.size
235
285
  end
236
286
 
237
287
  end
238
288
 
239
- describe '#variables' do
289
+ describe '#terminate!' do
240
290
 
241
- it 'should return a Hash of variables and their values' do
242
- skip 'until Variable added'
291
+ it 'should set the goal to terminate and log the event' do
292
+ goal = Goal.new args
243
293
 
244
- pred = Predicate.new :p
245
- args = pred.(:x,:y)
294
+ assert goal.terminate!, 'the goal should be set to terminate'
295
+ assert_equal ['terminating'], goal.log
296
+ end
297
+
298
+ end
299
+
300
+ describe '#terminated?' do
301
+
302
+ it 'should return whether the goal is set to terminate or not' do
303
+ goal = Goal.new args
246
304
 
305
+ refute goal.terminated?, 'the goal should not be initialized to terminate'
306
+ assert goal.terminate!, 'the goal should be set to terminate'
307
+ assert goal.terminated?, 'the goal should be set to terminate'
308
+ end
309
+
310
+ end
311
+
312
+ describe '#variablise' do
313
+
314
+ it 'should convert a Symbol into a Variable' do
315
+ assert_Variable goal.variablise(:k), :k, goal, [], []
316
+ end
317
+
318
+ it 'should return a Variable as is' do
319
+ v = Variable.new :r, goal
320
+ assert_equal v, goal.variablise(v)
321
+ end
322
+
323
+ it 'should convert an Array into a Variables and Objects' do
324
+ assert_equal [goal.value(1),goal.variable(:a),goal.value('word')], goal.variablise([1,:a,'word'])
325
+ end
326
+
327
+ it 'should return a duplicate of an Arguments' do
328
+ duplicate = goal.variablise(args)
329
+ assert_Arguments duplicate, :p, goal.variablise([:x, :y])
330
+ refute_equal args, duplicate
331
+ end
332
+
333
+ it 'should convert a Tail into a Tail with a variablised value' do
334
+ assert_Tail goal.variablise(Tail.new :m), '*Goal1.:m'
335
+ end
336
+
337
+ it 'should return a Value as is' do
338
+ v = Value.new(45, goal)
339
+ assert_equal v, goal.variablise(v)
340
+ end
341
+
342
+ it 'should return an unknown array as is' do
343
+ assert_equal UNKNOWN_ARRAY, goal.variablise(UNKNOWN_ARRAY)
344
+ end
345
+
346
+ it 'should return an unknown tail as is' do
347
+ assert_equal UNKNOWN_TAIL, goal.variablise(UNKNOWN_TAIL)
348
+ end
349
+
350
+ it 'should convert any other Object into a Value' do
351
+ assert_Value goal.variablise(23.61), 23.61, goal
352
+ end
353
+
354
+ end
355
+
356
+ describe '#variables' do
357
+
358
+ it 'should return a Hash of variables and their values' do
247
359
  goal = Goal.new args
248
360
  goal.variable(:x)
249
361
  goal.variable(:y)
@@ -254,26 +366,148 @@ describe 'Porolog' do
254
366
  assert_instance_of Hash, variables
255
367
 
256
368
  assert_Goal goal, :p, [:x,:y]
257
- assert_Goal_variables goal, { x: nil, y: nil, z: nil }, ''
369
+ assert_Goal_variables goal, { x: nil, y: nil, z: nil }, [
370
+ 'Goal1.:x',
371
+ 'Goal1.:y',
372
+ 'Goal1.:z',
373
+ ].join("\n")
258
374
  end
259
375
 
260
376
  end
261
377
 
262
- describe '#variable' do
378
+ describe '#inspect_variables' do
263
379
 
264
- let(:pred) { Predicate.new :p }
265
- let(:args) { pred.(:x,:y) }
266
- let(:goal) { Goal.new args }
380
+ it 'should return a string showing the instantiations of the variables of the goal' do
381
+ # -- Initial Goal --
382
+ goal = Goal.new args
383
+
384
+ x = goal.variable(:x)
385
+ y = goal.variable(:y)
386
+ z = goal.variable(:z)
387
+
388
+ expected = [
389
+ 'Goal1.:x',
390
+ 'Goal1.:y',
391
+ 'Goal1.:z',
392
+ ].join("\n")
393
+
394
+ assert_equal expected, goal.inspect_variables
395
+
396
+ # -- After First Instantiation --
397
+ # x.head = y
398
+ x.instantiate y, nil, :head
399
+
400
+ expected = [
401
+ 'Goal1.:x',
402
+ ' [:head]Goal1.:y',
403
+ 'Goal1.:y',
404
+ ' Goal1.:x[:head]',
405
+ 'Goal1.:z',
406
+ ].join("\n")
407
+
408
+ assert_equal expected, goal.inspect_variables
409
+
410
+ # -- After Second Instantiation --
411
+ # x.head = y
412
+ # x.tail = z
413
+ x.instantiate z, nil, :tail
414
+
415
+ expected = [
416
+ 'Goal1.:x',
417
+ ' [:head]Goal1.:y',
418
+ ' [:tail]Goal1.:z',
419
+ 'Goal1.:y',
420
+ ' Goal1.:x[:head]',
421
+ ' [:tail]Goal1.:z',
422
+ 'Goal1.:z',
423
+ ' Goal1.:x[:tail]',
424
+ ' [:head]Goal1.:y',
425
+ ].join("\n")
426
+
427
+ assert_equal expected, goal.inspect_variables
428
+
429
+ # -- After Third Instantiation --
430
+ # x = [*y, *z]
431
+ # y = 1,2,3
432
+ y.instantiate goal.value([1,2,3])
433
+
434
+ expected = [
435
+ 'Goal1.:x',
436
+ ' [:head]Goal1.:y',
437
+ ' Goal1.[1, 2, 3]',
438
+ ' [:tail]Goal1.:z',
439
+ 'Goal1.:y',
440
+ ' Goal1.:x[:head]',
441
+ ' [:tail]Goal1.:z',
442
+ ' Goal1.[1, 2, 3]',
443
+ 'Goal1.:z',
444
+ ' Goal1.:x[:tail]',
445
+ ' [:head]Goal1.:y',
446
+ ' Goal1.[1, 2, 3]',
447
+ ].join("\n")
448
+
449
+ assert_equal expected, goal.inspect_variables
450
+
451
+ # -- After Fourth Instantiation --
452
+ # x = [*y, *z]
453
+ # y = 1,2,3
454
+ # z = 4,5,6
455
+ z.instantiate goal.value([4,5,6])
456
+
457
+ expected = [
458
+ 'Goal1.:x',
459
+ ' [:head]Goal1.:y',
460
+ ' Goal1.[1, 2, 3]',
461
+ ' [:tail]Goal1.:z',
462
+ ' Goal1.[4, 5, 6]',
463
+ 'Goal1.:y',
464
+ ' Goal1.:x[:head]',
465
+ ' [:tail]Goal1.:z',
466
+ ' Goal1.[4, 5, 6]',
467
+ ' Goal1.[1, 2, 3]',
468
+ 'Goal1.:z',
469
+ ' Goal1.:x[:tail]',
470
+ ' [:head]Goal1.:y',
471
+ ' Goal1.[1, 2, 3]',
472
+ ' Goal1.[4, 5, 6]',
473
+ ].join("\n")
474
+
475
+ assert_equal expected, goal.inspect_variables
476
+ end
267
477
 
268
- it 'should return a non-variable as is' do
269
- skip 'until Variable added'
478
+ end
479
+
480
+ describe '#values' do
481
+
482
+ it 'should return the values that have been associated with the goal' do
483
+ goal = Goal.new args
270
484
 
485
+ x = goal.variable(:x)
486
+ y = goal.variable(:y)
487
+ z = goal.variable(:z)
488
+
489
+ x.instantiate y, nil, :head
490
+ x.instantiate z, nil, :tail
491
+ y.instantiate goal.value([1,2,3])
492
+ z.instantiate goal.value([4,5,6])
493
+
494
+ expected = [
495
+ [1,2,3],
496
+ [4,5,6],
497
+ ]
498
+
499
+ assert_equal expected, goal.values
500
+ end
501
+
502
+ end
503
+
504
+ describe '#variable' do
505
+
506
+ it 'should return a non-variable as is' do
271
507
  assert_equal 4.132, goal.variable(4.132)
272
508
  end
273
509
 
274
510
  it 'should create and find a variable from a Symbol or Variable' do
275
- skip 'until Variable added'
276
-
277
511
  refute goal.variables.key?(:v), ':v should not be a variable'
278
512
 
279
513
  variable1 = goal.variable :v
@@ -292,26 +526,40 @@ describe 'Porolog' do
292
526
 
293
527
  end
294
528
 
295
- describe '#value_of' do
529
+ describe '#value' do
296
530
 
297
- let(:pred) { Predicate.new :p }
298
- let(:args) { pred.(:x,:y) }
299
- let(:goal) { Goal.new args }
531
+ it 'should create and find a value from an Object' do
532
+ refute goal.values.include?(99.02), '99.02 should not be a value'
533
+
534
+ value1 = goal.value 99.02
535
+
536
+ assert goal.values.include?(99.02), '99.02 should be a value'
537
+
538
+ value2 = goal.value 99.02
539
+
540
+ assert_Value value1, 99.02, goal
541
+ assert_Value value2, 99.02, goal
542
+
543
+ assert_equal [99.02], goal.values
544
+ end
545
+
546
+ end
547
+
548
+ describe '#value_of' do
300
549
 
301
550
  describe 'when name is a Symbol' do
551
+
302
552
  let(:variable_name) { :cymbal }
303
553
 
304
554
  it 'should create the Variable' do
305
- skip 'until Variable added'
306
-
307
555
  refute goal.variables.key?(variable_name), "#{variable_name} should not exist"
308
556
 
309
- assert_nil goal.value_of(variable_name)
557
+ refute_nil goal.value_of(variable_name)
310
558
 
311
559
  assert goal.variables.key?(variable_name), "#{variable_name} should exist"
312
560
 
313
561
  variable = goal.variable(variable_name)
314
- variable.value = 44.5
562
+ variable.instantiate 44.5
315
563
 
316
564
  assert_equal 44.5, goal.value_of(variable_name)
317
565
  end
@@ -319,6 +567,7 @@ describe 'Porolog' do
319
567
  end
320
568
 
321
569
  describe 'when name is not a Symbol' do
570
+
322
571
  let(:variable_name) { 99.28 }
323
572
 
324
573
  it 'should return the name as the value' do
@@ -329,11 +578,55 @@ describe 'Porolog' do
329
578
 
330
579
  end
331
580
 
581
+ describe '#values_of' do
582
+
583
+ it 'should return an Array with values_of applied to each element when given an Array' do
584
+ goal.instantiate :thomas, '$10'
585
+
586
+ expected = [[1,'two'], '$10', 999, 'giraffe', 0.5]
587
+
588
+ assert_equal expected, goal.values_of([[1,'two'], :thomas, 999, 'giraffe', 0.5])
589
+ end
590
+
591
+ it 'should return the value_of the Variable when given a Variable' do
592
+ goal.instantiate :jones, 'Fuzzy'
593
+
594
+ variable1 = goal.variable(:jones)
595
+
596
+ assert_equal 'Fuzzy', goal.values_of(variable1)
597
+ end
598
+
599
+ it 'should return the value_of the Symbol when given a Symbol' do
600
+ goal.instantiate :x, 'Staunch'
601
+
602
+ assert_equal 'Staunch', goal.values_of(:x)
603
+ end
604
+
605
+ it 'should return the value_of the Value when given a Value' do
606
+ value1 = goal.value(123.76)
607
+
608
+ assert_equal 123.76, goal.values_of(value1)
609
+ end
610
+
611
+ it 'should somehow splat when given a Tail' do
612
+ tail1 = Tail.new ['apples','oranges','bananas']
613
+
614
+ assert_equal 'apples', goal.values_of(tail1)
615
+ end
616
+
617
+ it 'should return the Object as is when given an Object' do
618
+ object = Object.new
619
+
620
+ goal.expects(:value_of).times(0)
621
+
622
+ assert_equal object, goal.values_of(object)
623
+ end
624
+
625
+ end
626
+
332
627
  describe '#solve' do
333
628
 
334
629
  it 'should find no solutions for a goal with no rules' do
335
- skip 'until CoreExt added'
336
-
337
630
  goal1 = new_goal :p, :x, :y
338
631
 
339
632
  solutions = goal1.solve
@@ -342,8 +635,6 @@ describe 'Porolog' do
342
635
  end
343
636
 
344
637
  it 'should solve a fact' do
345
- skip 'until CoreExt added'
346
-
347
638
  predicate :fact
348
639
 
349
640
  fact(42).fact!
@@ -354,8 +645,6 @@ describe 'Porolog' do
354
645
  end
355
646
 
356
647
  it 'should not solve a falicy' do
357
- skip 'until CoreExt added'
358
-
359
648
  predicate :fact
360
649
 
361
650
  fact(42).falicy!
@@ -366,8 +655,6 @@ describe 'Porolog' do
366
655
  end
367
656
 
368
657
  it 'should solve using head and tail with lists' do
369
- skip 'until HeadTail added'
370
-
371
658
  predicate :head_tail
372
659
 
373
660
  head_tail([1,2,3,4,5,6,7]).fact!
@@ -382,7 +669,8 @@ describe 'Porolog' do
382
669
  end
383
670
 
384
671
  it 'should solve a goal recursively' do
385
- skip 'until HeadTail added'
672
+ #:nocov:
673
+ skip 'until Standard Predicates added'
386
674
 
387
675
  predicate :recursive
388
676
 
@@ -397,7 +685,126 @@ describe 'Porolog' do
397
685
 
398
686
  assert_equal [{}], solutions
399
687
  end
688
+ #:nocov:
689
+ end
690
+
691
+ end
692
+
693
+ describe '#satisfy' do
694
+
695
+ let(:block) { ->(subgoal){} }
696
+
697
+ it 'should return false when the goal has no arguments' do
698
+ goal = Goal.new nil
699
+
700
+ block.expects(:call).times(0)
701
+
702
+ refute goal.satisfy(&block), name
703
+ end
704
+
705
+ it 'should access the predicate of its arguments' do
706
+ goal.arguments.expects(:predicate).with().returns(nil).times(1)
707
+ block.expects(:call).times(0)
708
+
709
+ assert_nil goal.satisfy(&block), name
710
+ end
711
+
712
+ it 'should try to satisfy the predicate with itself' do
713
+ pred.expects(:satisfy).with(goal).returns(nil).times(1)
714
+ block.expects(:call).times(0)
715
+
716
+ assert_nil goal.satisfy(&block), name
717
+ end
718
+
719
+ it 'should call the block when the predicate is satisfied' do
720
+ pred.(1,2).fact!
721
+ pred.(3,4).fact!
722
+ pred.(5,6).fact!
723
+
724
+ block.expects(:call).times(3)
725
+
726
+ assert goal.satisfy(&block), name
727
+ end
728
+
729
+ end
730
+
731
+ describe '#instantiate' do
732
+
733
+ it 'creates an Array with a Tail using the slash notation with Symbols with a goal' do
734
+ goal = new_goal :bravo, :x, :y, :z
735
+
736
+ head_tail = goal.variablise(:head / :tail)
737
+
738
+ assert_Array_with_Tail head_tail, [goal.variable(:head)], '*Goal1.:tail'
739
+
740
+ assert_Goal_variables goal, { x: nil, y: nil, z: nil, head: nil, tail: nil }, [
741
+ 'Goal1.:x',
742
+ 'Goal1.:y',
743
+ 'Goal1.:z',
744
+ 'Goal1.:head',
745
+ 'Goal1.:tail',
746
+ ].join("\n")
747
+ end
748
+
749
+ it 'creates an Array with a Tail using the slash notation with a single head with a goal' do
750
+ goal = new_goal :bravo, :x, :y, :z
751
+
752
+ head_tail = goal.variablise([:head] / :tail)
753
+
754
+ assert_Array_with_Tail head_tail, [goal.variable(:head)], '*Goal1.:tail'
755
+
756
+ assert_Goal_variables goal, { x: nil, y: nil, z: nil, head: nil, tail: nil }, [
757
+ 'Goal1.:x',
758
+ 'Goal1.:y',
759
+ 'Goal1.:z',
760
+ 'Goal1.:head',
761
+ 'Goal1.:tail',
762
+ ].join("\n")
763
+ end
764
+
765
+ it 'creates variables from its contents with a goal' do
766
+ predicate :bravo
767
+ arguments = Predicate[:bravo].arguments(:x,:y,:z)
768
+ goal = arguments.goal
769
+
770
+ head_tail = [:alpha,bravo(:a,:b,:c),[:carly]] / [:x,[:y],bravo(:p,:q/:r)]
771
+
772
+ assert_equal [:alpha,bravo(:a,:b,:c),[:carly], :x,[:y],bravo(:p,:q/:r)].inspect, head_tail.inspect
773
+
774
+ assert_Goal_variables goal, { x: nil, y: nil, z: nil }, [
775
+ 'Goal1.:x',
776
+ 'Goal1.:y',
777
+ 'Goal1.:z',
778
+ ].join("\n")
779
+
780
+ head_tail = goal.variablise(head_tail)
781
+
782
+ assert_equal '[Goal1.:alpha, bravo(Goal1.:a,Goal1.:b,Goal1.:c), [Goal1.:carly], Goal1.:x, [Goal1.:y], bravo(Goal1.:p,[Goal1.:q, *Goal1.:r])]', head_tail.inspect
783
+
784
+ assert_Goal_variables goal, { x: nil, y: nil, z: nil, alpha: nil, a: nil, b: nil, c: nil, carly: nil, p: nil, q: nil, r: nil }, [
785
+ 'Goal1.:x',
786
+ 'Goal1.:y',
787
+ 'Goal1.:z',
788
+ 'Goal1.:alpha',
789
+ 'Goal1.:a',
790
+ 'Goal1.:b',
791
+ 'Goal1.:c',
792
+ 'Goal1.:carly',
793
+ 'Goal1.:p',
794
+ 'Goal1.:q',
795
+ 'Goal1.:r',
796
+ ].join("\n")
797
+ end
798
+
799
+ it 'should combine Array value of head and Array value of tail when it has a goal' do
800
+ head_tail = [:first] / :last
801
+
802
+ goal.instantiate :first, 'alpha', goal
803
+ goal.instantiate :last, ['omega'], goal
804
+
805
+ head_tail = goal.values_of(goal.variablise(head_tail))
400
806
 
807
+ assert_equal ['alpha','omega'], head_tail
401
808
  end
402
809
 
403
810
  end