z ← l (fn ##.bags) r ⍝ Multisets/bags. Operator [bags] models the Parks-Smith proposal for a $ operator, which adds Multisets to APL. A "Multiset" or "bag" has attributes of both a vector and a set in that, like a vector, it may have duplicate items and, like a set, the order of its items is not significant. [bags] is an operator, which treats its arguments as if they were multisets. 1 2 2 3 ≡bags 2 1 3 2 ⍝ multiset item-order is not significant. 1 1 2 2 3 ≡bags 1 2 3 3 ⍝ multiset duplicate count is significant. 0 Illustration ------------ Given two vectors, which we want to view as multisets: A ← 2 1 2 1 3 2 5 B ← 3 4 2 1 2 3 By permuting the vector items and indenting the second one, we can arrange that all coincident items (if any) are aligned: ┌───────── ⍝ coincident items 1 2 2 3 ┌──┴──┐ A ← 1 2 5 1 2 2 3 ⍝ permutation of 1st vector. B ← 1 2 2 3 4 3 ⍝ .. 2nd .. └─────┘ now various multiset functions can be illustrated so: ┌───────────────── A ~bags B → 1 2 5 ⍝ asymmetric difference. │ ┌────────── A ∩bags B → 1 2 2 3 ⍝ intersection. ┌─┴─┐ ┌──┴──┐ ┌──── B ~bags A → 4 3 ⍝ asymmetric difference. A ← 1 2 5 1 2 2 3 ┌┴┐ B ← │ │ 1 2 2 3 4 3 └─┬─┘ └─────┘ └┬┘ │ └────────────┴── A('§'bags)B → 1 2 5 4 3 ⍝ symmetric difference. └───────┬───────┘ └─────────── A ∪bags B → 1 2 5 1 2 2 3 4 3 ⍝ union. Searching functions ⍳ and ∊ take account of duplicate items in multisets: 8 7 8 ⍳bags 8 8 8 8 1 3 4 4 8 8 8 8 ∊bags 8 7 8 1 1 0 0 In all, bags is defined for operands: ≡ match. ≢ natch. ~ multiset asymmetric difference (MAD) '§' multiset symmetric difference (MSD) * ∪ unique/union. ∩ intersection. ∊ progressive membership. Smith [2] ⍳ progressive dyadic iota. FinnAPL Idiom List [3] [*] operand § must be enclosed in quotes, see example below. Note also that the derived function ('§'bags) must be parenthesised in order to prevent operand '§' from binding with the left argument: larg('§'bags)rarg. Alternatively, we might prefer to name '§'bags: 1 2 3 ('§'bags) 2 3 4 1 4 msd ← '§'bags 1 2 3 msd 2 3 4 1 4 To allow for extending this operand set in the future, operands not in this list generate a NONCE ERROR. Refs: [0] Parks-Smith paper "Proposal for Multiset Features in APL" [1] http://en.wikipedia.org/wiki/Multiset [2] http://www.sudleyplace.com/APL/AnatomyOfAnIdiom.ahtml [3] http://nsg.upor.net/jpage/finnapl.pdf Examples: 1 2 3 1 2 3 ~bags 1 1 3 1 ⍝ multiset asymmetric difference (MAD) 2 2 3 1 1 1 2 2 3 ('§'bags) 1 2 2 3 3 3 ⍝ multiset symmetric difference (MSD) 1 1 3 3 1 2 3 1 2 3 ⍳bags 1 1 3 1 ⍝ progressive dyadic iota (PDI) 1 4 3 7 3 1 3 ∊bags 3 1 1 2 ⍝ progressive dyadic epsilon (PDE) 1 1 0 (⊂1 2 2) ≡bags¨ (1 2)(2 2 1)(1 1 2) ⍝ match 0 1 0 (⊂1 2 2) ≢bags¨ (1 2)(2 2 1)(1 1 2) ⍝ natch 1 0 1 1 2 2 3 ∪bags 2 3 3 ⍝ union 1 2 2 3 3 ∪bags 1 1 2 2 ⍝ unique is a no-op 1 1 2 2 1 2 2 3 ∩bags 2 3 3 2 ⍝ intersection 2 2 3 1 2 3 3 1 2 3 ,bags 3 1 3 ⍝ non-multiset function 1 2 3 3 1 2 3 3 1 3 'tick' 'tock' ≡bags 'tock' 'tick' ⍝ nested args. 1 A←?10/5 ⋄ B←?10/5 ⍝ vectors with repeated items. (A ∪bags B) ≡bags (B ∪bags A) ⍝ multiset-union is commutative. 1 (A ∩bags B) ≡bags (B ∩bags A) ⍝ multiset-intersection is commutative. 1 msd←'§'bags ⋄ (A msd B) ≡bags (B msd A) ⍝ MSD is commutative. 1 (⍳⍴A) ≡ A ⍳bags A ⍝ progressive dyadic iota. 1 Back to: contents Back to: Workspaces