Consider the following Alloy model:
open util/ordering[C]
abstract sig A {}
sig B extends A {}
sig C extends A {}
pred show {}
run show for 7
I understand why, when I run show for 7
, all the instances of this model have 7 atoms of signature C. (Well, that's not quite true. I understand that the ordered signature will always have as many atoms as the scope allows, because util/ordering tells me so. But that's not quite the same as why.)
But why do no instances of this model have any atoms of signature B? Is this a side-effect of the special handling performed for util/ordering? (Intended? Unintended?) Is util/ordering intended to be applied only to top-level signatures?
Or is there something else going on that I am missing?
In the model from this this is abstracted, I'd really like to have a name like A for the union of B and C, and I'd really like C to be ordered, and I'd really like B to be unordered and non-empty. At the moment, I seem to able to achieve any two of those goals; is there a way to manage all three at the same time?
[Addendum: I notice that specifying run show for 3 but 3 B, 3 C
does achieve my three goals. By contrast, run show for 2 but 3 B
produces no instances at all. Perhaps I need to understand the semantics of scope specifications better.]
Short answer: the phenomena reported result from the rules for default and implicit scopes; those rules are discussed in section B.7.6 of the Language Reference.
Longer answer:
The eventual suspicion that I should look at the semantics of scope specifications more closely proved to be warranted. In the example shown here, the rules work out exactly as documented:
For
run show for 7
, signature A has a default scope of 7; so do B and C. The use of the util/ordering module forces the number of C atoms to 7; that also exhausts the quota for signature A, which leaves signature B with an implicit scope of 0.For
run show for 2 but 3 B
, signature A has a default scope of 2, and B has an explicit scope of 3. This leaves signature C with an implicit signature of 2 minus 3, or negative 1. That appears to count as an inconsistency; scope bounds are expected to be natural numbers.For
run show for 2 but 3 B, 3 C
, signature A gets an implicit bound of 6 (the sum of its subsignatures' bounds).As a way of gaining a better understanding of the scope rules, it proved useful to this user to execute all of the following commands:
I'll leave this question in place for other answers and in the hope that it may help some other users.
The reason is that when forcing an ordered sig to contain as many atoms as the scope allows it is possible for the translator to generate an efficient symmetry breaking predicate, which, in most examples with ordered sigs, results in much better solving time. So it is simply a trade-off, and the design decision was to enforce this extra constraint in order to gain performance.