Question

Is there a way to model a system using bags(multisets) as well in Alloy? And if there is no explicit notion of bags, is there any possible workaround?

Thanks.

Was it helpful?

Solution 2

Thanks for all your help but I did it the following way eventually:

First I restricted my bags to contain only elements with non-zero multiplicity

module bags

open util/natural
open util/relation

sig Element{}

sig Bag{
    elements: Element -> one Natural
}{
    all e: Element.elements | e != Zero
}

And coded union/difference/intersection like this:

fun BagUnion[b1, b2 : Element -> one Natural]: Element -> one Natural{
    let e = (dom[b1] + dom[b2]) | e -> add[e.b1, e.b2]  
}

fun BagDifference[b1, b2 : Element -> one Natural]: Element -> one Natural{
    let e = dom[b1] | e -> max[Zero + sub[e.b1, e.b2]] 
}

fun BagIntersection[b1, b2 : Element -> one Natural]: Element -> one Natural{
    let e = (dom[b1] & dom[b2]) | e -> min[e.b1 + e.b2] 
}

OTHER TIPS

A multiset [aka bag] of E is representable by a function E ->one Natural, or E ->lone (Natural-Zero) (depending on taste as to how to handle absence).

open util/natural
sig E {}
sig A { m : E -> one Natural }
sig B { n : E -> lone (Natural-Zero) }

fun bagunion[m, n : univ -> lone Natural]: univ -> lone Natural
{ e : (m+n).univ, x : Natural |      e in m.univ-n.univ implies x=e.m
                                else e in n.univ-m.univ implies x=e.n
                                else x=add[e.m, e.n]                  }

There are probably neater ways to do bag union.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top