Skip to content

Commit 221c222

Browse files
fold operations for bags
1 parent 3cb18ad commit 221c222

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

modules/BagsExt.tla

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
(***************************************************************************)
55

66
LOCAL INSTANCE Bags
7-
LOCAL INSTANCE Naturals
7+
LOCAL INSTANCE Integers
88
LOCAL INSTANCE Folds
99

1010
BagAdd(B, x) ==
1111
(************************************************************************)
1212
(* Add an element x to bag B. *)
13+
(* Same as B (+) SetToBag({x}). *)
1314
(************************************************************************)
1415
IF x \in DOMAIN B
1516
THEN [e \in DOMAIN B |-> IF e=x THEN B[e]+1 ELSE B[e]]
@@ -18,11 +19,43 @@ BagAdd(B, x) ==
1819
BagRemove(B,x) ==
1920
(************************************************************************)
2021
(* Remove an element x from bag B. *)
22+
(* Same as B (-) SetToBag({x}). *)
2123
(************************************************************************)
2224
IF x \in DOMAIN B
2325
THEN IF B[x] = 1
2426
THEN [e \in DOMAIN B \ {x} |-> B[e]]
2527
ELSE [e \in DOMAIN B |-> IF e=x THEN B[e]-1 ELSE B[e]]
2628
ELSE B
2729

30+
FoldBag(op(_,_), base, B) ==
31+
(************************************************************************)
32+
(* Fold op over all elements of bag B, starting with value base. *)
33+
(* *)
34+
(* Example: *)
35+
(* FoldBag(LAMBDA x,y : x+y, *)
36+
(* 0, *)
37+
(* (1 :> 2) @@ (2 :> 1) @@ (3 :> 2)) = 10 *)
38+
(* The third argument represents the bag {| 1, 1, 2, 3, 3 |}. *)
39+
(************************************************************************)
40+
LET repl(x) ==
41+
(* replicate operation op for all occurrences of x in B *)
42+
LET it[n \in Nat \ {0}] ==
43+
IF n = 1 THEN x ELSE op(x, it[n-1])
44+
IN it[B[x]]
45+
IN MapThenFoldSet(op, base, repl,
46+
LAMBDA S : CHOOSE x \in S : TRUE,
47+
DOMAIN B)
48+
49+
SumBag(B) ==
50+
(************************************************************************)
51+
(* Compute the sum of the elements of B. *)
52+
(************************************************************************)
53+
FoldBag(LAMBDA x,y : x+y, 0, B)
54+
55+
ProductBag(B) ==
56+
(************************************************************************)
57+
(* Compute the product of the elements of B. *)
58+
(************************************************************************)
59+
FoldBag(LAMBDA x,y : x*y, 1, B)
60+
2861
=============================================================================

tests/BagsExtTests.tla

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---- CONFIG BagsExtTests ----
2+
INIT Init
3+
NEXT Next
4+
=====
5+
6+
---------------------------- MODULE BagsExtTests ----------------------------
7+
EXTENDS Integers, TLC, Bags, BagsExt
8+
9+
ASSUME LET T == INSTANCE TLC IN T!PrintT("BagsExtTests")
10+
11+
-----------------------------------------------------------------------------
12+
13+
ASSUME LET B == SetToBag({1,2}) IN BagAdd(B,2) = B (+) SetToBag({2})
14+
ASSUME LET B == SetToBag({1,2}) IN BagAdd(B,3) = B (+) SetToBag({3})
15+
ASSUME LET B == SetToBag({1,2}) IN BagRemove(B,2) = B (-) SetToBag({2})
16+
ASSUME LET B == SetToBag({1,2}) IN
17+
/\ BagRemove(B,3) = B (-) SetToBag({3})
18+
/\ BagRemove(B,3) = B
19+
20+
-----------------------------------------------------------------------------
21+
22+
ASSUME FoldBag(LAMBDA x,y : x+y, 0, (1:>2) @@ (2:>1) @@ (3:>2)) = 10
23+
ASSUME FoldBag(LAMBDA x,y : x+y, 0, (1:>2) @@ (-2:>1)) = 0
24+
25+
ASSUME SumBag((1:>2) @@ (2:>1) @@ (3:>2)) = 10
26+
ASSUME SumBag((1:>2) @@ (-2:>1)) = 0
27+
28+
ASSUME ProductBag((1:>2) @@ (-2:>1)) = -2
29+
ASSUME ProductBag((1:>2) @@ (0:>1) @@ (10000:>1)) = 0
30+
31+
=============================================================================

0 commit comments

Comments
 (0)