@@ -164,6 +164,16 @@ module Knowledge : sig
164
164
value of the property domain is returned as the result. *)
165
165
val collect : ('a ,'p) slot -> 'a obj -> 'p t
166
166
167
+ (* * [require p x] collects the property [p] and fails if it is empty.
168
+
169
+ When [require p x] fails in the scope of a {!promise},
170
+ {!proposal}, or in the scope of [with_empty], then the scoped
171
+ computation immediately returns the empty value.
172
+
173
+ @since 2.4.0
174
+ *)
175
+ val require : ('a ,'p) slot -> 'a obj -> 'p t
176
+
167
177
168
178
(* * [resolve p x] resolves the multi-opinion property [p]
169
179
@@ -186,6 +196,7 @@ module Knowledge : sig
186
196
then [provide p x v] diverges into a conflict.
187
197
*)
188
198
val provide : ('a ,'p) slot -> 'a obj -> 'p -> unit t
199
+
189
200
(* * [suggest a p x v] suggests [v] as the value for the property [p].
190
201
191
202
The same as [provide] except the provided value is predicated by
@@ -195,26 +206,35 @@ module Knowledge : sig
195
206
196
207
(* * [promise p f] promises to compute the property [p].
197
208
198
- If no knowledge exists about the property [p] of
199
- an object [x], then [f x] is invoked to provide an
200
- initial value.
209
+ If the property [p] of [x] is not provided, then [f x] is
210
+ invoked to provide the initial value, when [p] is collected.
201
211
202
212
If there are more than one promises, then they all must
203
213
provide a consistent answer. The function [f] may refer
204
214
to the property [p] directly or indirectly. In that case
205
215
the least fixed point solution of all functions [g] involved
206
216
in the property computation is computed.
217
+
218
+ @since 2.4.0 if [require] is called in the scope of the promise
219
+ and fails, the the whole promise immediately returns the empty
220
+ value of the property domain, i.e., [f] is wrapped into
221
+ [with_missing].
207
222
*)
208
223
val promise : ('a ,'p) slot -> ('a obj -> 'p t ) -> unit
209
224
210
-
211
225
(* * [promising p ~promise f] evaluates [f ()] under [promise] and
212
226
retracts it after [f] is evaluated.
213
227
214
228
The information provided by [promise] is only available during
215
229
evaluation of [f ()].
216
230
217
231
@since 2.2.0
232
+
233
+
234
+ @since 2.4.0 if [require] is called in the scope of the promise
235
+ and fails, the the whole promise immediately returns the empty
236
+ value of the property domain, i.e., [promise] (not [f]) wrapped
237
+ into [with_missing].
218
238
*)
219
239
val promising : ('a ,'p) slot -> promise :('a obj -> 'p t ) ->
220
240
(unit -> 's t ) -> 's t
@@ -223,6 +243,12 @@ module Knowledge : sig
223
243
224
244
The same as [promise] except that it promises a value for
225
245
an opinion-based property.
246
+
247
+ @since 2.4.0 if [require] is called in the scope of the promise
248
+ and fails, the the whole promise immediately returns the empty
249
+ value of the property domain, i.e., [f] is wrapped into
250
+ [with_missing].
251
+
226
252
*)
227
253
val propose : agent -> ('a , 'p opinions ) slot -> ('a obj -> 'p t ) -> unit
228
254
@@ -233,10 +259,25 @@ module Knowledge : sig
233
259
value for an opinion-based property.
234
260
235
261
@since 2.2.0
262
+
263
+ @since 2.4.0 if [require] are called in the scope of the proposal
264
+ and fails, the the whole proposal immediately returns the empty
265
+ value of the property domain, i.e., [propose] (not [f]) wrapped
266
+ into [with_missing].
267
+
236
268
*)
237
269
val proposing : agent -> ('a , 'p opinions ) slot ->
238
270
propose :('a obj -> 'p t ) -> (unit -> 's t ) -> 's t
239
271
272
+
273
+ (* * [with_empty ~missing f x] evaluates [f ()] and if it fails on an empty
274
+ immediately evaluates to [return missing].
275
+
276
+ @since 2.4.0
277
+ *)
278
+ val with_empty : missing :'r -> (unit -> 'r knowledge ) -> 'r knowledge
279
+
280
+
240
281
(* * state with no knowledge *)
241
282
val empty : state
242
283
@@ -333,10 +374,62 @@ module Knowledge : sig
333
374
include Monad.Syntax. S with type 'a t := 'a t
334
375
335
376
336
- (* * [x-->p] is [collect p x] *)
377
+ (* * the monadic let-binding operators.
378
+
379
+ Brings [let*] for [bind] and [let+] for [map] to the scope
380
+ of the [Syntax] module.
381
+
382
+ @since 2.4.0 (before that an explicit [open Knowledge.Let] was
383
+ required. *)
384
+ include Monad.Syntax.Let. S with type 'a t := 'a t
385
+
386
+
387
+ (* * [let*? v = x in f] evaluates to [f y] if [v] is [Some r].
388
+
389
+ Otherwise evaluates to [return None].
390
+
391
+ This let-binding operator is synonumous to [>>=?]
392
+
393
+ @since 2.4.0
394
+ *)
395
+ val (let *? ) : 'a option t -> ('a -> 'b option t) -> 'b option t
396
+
397
+ (* * [let+? v = x in f] evaluates to [!!(f y)] if [v] is [Some r].
398
+
399
+ Otherwise evaluates to [return None].
400
+
401
+ This let-binding operator is synonumous to [>>|?]
402
+
403
+ @since 2.4.0
404
+ *)
405
+ val (let +? ) : 'a option t -> ('a -> 'b option ) -> 'b option t
406
+
407
+ (* * [x-->p] is [collect p x].
408
+
409
+ Example,
410
+ {[
411
+ let* addr = label-->address in
412
+ ...
413
+ ]}
414
+ *)
337
415
val (--> ) : 'a obj -> ('a,'p) slot -> 'p t
338
416
339
417
418
+ (* * [x-->?p] returns property [p] if it is not empty.
419
+
420
+ Otherwise, if [x-->p] evaluates to empty or to [None]
421
+ fails with the empty value conflict.
422
+
423
+ Example,
424
+ {[
425
+ let* addr = label-->?address in
426
+ ...
427
+ ]}
428
+
429
+ See also {!with_empty}. *)
430
+ val (-->? ) : 'a obj -> ('a, 'p option ) slot -> 'p t
431
+
432
+
340
433
(* * [p <-- f] is [promise p f] *)
341
434
val (< -- ) : ('a,'p) slot -> ('a obj -> 'p t) -> unit
342
435
@@ -351,6 +444,42 @@ module Knowledge : sig
351
444
352
445
(* * [x >>|? f] evaluates to [f y] if [x] evaluates to [Some y]. *)
353
446
val (>> |? ) : 'a option t -> ('a -> 'b option ) -> 'b option t
447
+
448
+
449
+ (* * [x.$[p]] is the propery [p] of [x].
450
+
451
+ @since 2.4.0
452
+ *)
453
+ val (.$ [] ) : ('a,_) cls value -> ('a,'p) slot -> 'p
454
+
455
+
456
+ (* * [x.$[p] <- r] updates the property [p] of [x] to [r].
457
+
458
+ Returns the value [x] with the new property. The previous
459
+ value is ignored so there is no merging or monotonicity check
460
+ involved.
461
+
462
+ @since 2.4.0 *)
463
+ val (.$ [] < - ) : ('a,'b) cls value -> ('a,'p) slot -> 'p -> ('a,'b) cls value
464
+
465
+
466
+ (* * [x.?[p]] returns the non-[None] property [p] or fails.
467
+
468
+ The result is [return r] when [x.$[p]] is [Some r] or a
469
+ knowledge base conflict otherwise.
470
+
471
+ @since 2.4.0
472
+ *)
473
+ val (.?[] ) : ('a,_) cls value -> ('a,'p option ) slot -> 'p knowledge
474
+
475
+ (* * [x.![p]] returns the property [p] or fails if it is empty.
476
+
477
+ The result is [return r] if not [Domain.is_empty dom r],
478
+ where [dom] is [Slot.domain p].
479
+
480
+ @since 2.4.0
481
+ *)
482
+ val (.! [] ) : ('a,_) cls value -> ('a,'p) slot -> 'p knowledge
354
483
end
355
484
356
485
@@ -1388,7 +1517,6 @@ module Knowledge : sig
1388
1517
module Conflict : sig
1389
1518
type t = conflict = ..
1390
1519
1391
-
1392
1520
(* * [to_string err] is the textual representation of the conflict [err]
1393
1521
1394
1522
@since 2.2.0 *)
0 commit comments