I have the following model:
sig A1 {
// ...
}
sig A2 {
// ...
}
sig S {
s_a1: one A1,
s_a2: one A2
}
I'd like to "produce" a subset s1:S based on the elements of s0:S subject to the following constraints:
s1 has the same number of atoms as s0
those atoms s_valid in s0 that meet condition c1[s_valid.s_a1] must also be contained in s1
for each of those atoms s_invalid in s0 that does not meet c1[s_invalid.s_a1] there must be an atom in s1 with the same s_a1 but a different s_a2 association
The aim is to simulate the modification of some of the items in a collection.
I've tried to solve this problem with comprehension expressions but I can't find the right means to express the change in the s_a2 association.
something like this?
-- s1 has the same number of atoms as s0
#s1 = #s2
-- those atoms s_valid in s0 that meet condition c1[s_valid.s_a1] must also be contained in s1
{x: s0 | c1[x.s_a1]} in s1
-- for each of those atoms s_invalid in s0 that does not meet c1[s_invalid.s_a1] there must be an atom in s1 with the same s_a1 but a different s_a2 association
all x: s0 | not c1[x.s_a1] implies some y: s1 | y.s_a1 = x.s_a1 and y.s_a2 != x.s_a2
Related
The following Alloy predicate p has a parameter t declared as a singleton of type S. Invoke run p gives the correct result because the predicate body states that t may contain two different elements s and s'. However, in the second run command, a set of two disjoint elements of type S is passed into predicate p and this command gives an instance. Why is it the case?
sig S {}
pred p(t: one S) {
some s, s': t | s != s'
}
r1: run p -- no instance found
r2: run { -- instance found
some disj s0, s1: S {
S = s0 + s1
p[S]
}
}
See https://stackoverflow.com/a/43002442/1547046. Same issue, I think.
BTW, there's a nice research problem here. Can you define a coherent semantics for argument declarations that would be better (that is, simpler, unsurprising, and well defined in all contexts)?
I'm trying to notice a change in atom relations to other atoms. Using the below signatures :
sig Word, Definition{}
sig Dictionary {
def: Word -> lone Definition
}
I then use a predicate to show what happens when you add a new relation to a Dictionary by having another Dictionarywhich is the same but with one more relation.
pred addRelation [d,d':Dictionary,w:Word,f:Definition] {
d'.word = d.word + w -> f
}
To see if the number of Word atoms used by the first Dictionary increase I can show only the instances where this occurs using:
#d'.def.Definition > #d.def.Definition
However, is there a way to see if the number of Definition atoms used by the second Dictionary atom has increased? I've been using trial and error in the Alloy Evaluator to try and find a value for this but have come up short.
Thanks!
Like this?
sig Word, Definition{}
sig Dictionary {
def: Word -> lone Definition
}
pred addRelation [d,d':Dictionary,w:Word,f:Definition] {
d'.def = d.def + w -> f
#d'.def[Word] > #d.def[Word]
}
run addRelation
I was inspired by the slide http://alloy.mit.edu/alloy/tutorials/day-course/s4_dynamic.pdf of Greg Dennis and Rob Seater, to model an automaton whose transitions are defined by rules and invariances but I can not understand why satisfy the constraints even in the presence of invariances and contradictory rules.
sig State {value : one Int}
sig System { trans : State -> State }
pred i1[s : State] { s.value < 4 }
pred i2[s : State] { s.value > 0 }
pred r1[s, s' : State, m, m' : System] {
s.value = -1 and s'.value = 0 and change[s, s', m, m']
}
pred r2[s, s' : State, m, m' : System] {
s.value = 1 and s'.value = 2 and change[s, s', m, m']
}
pred change[s, s' : State, m, m' : System] {
m'.trans = m.trans + s -> s'
}
assert ruleSafe {
all s, s' : State, m,m' : System |
i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m'] =>
i1[s'] and i2[s']
}
check ruleSafe
First, a side note: It's not clear what the value relation is intended to be doing, but do remember that integers in Alloy tend to be very narrow and overflow behavior can make rules like s.value < 4 produce unexpected results. Whenever integers are used only to ensure a nice supply of distinct values, or ordered values it is almost always better to use an uninterpreted type in Alloy with some relations to ensure the necessary constraints.
However, that's not the main source of your confusion. I think you believe that since r1 requires its first argument to have a value of -1 and r2 requires the same argument to have a value of 1, any condition involving both r1 and r2 with the same first argument cannot possibly be satisfied, and there can be no instances of a model which is required to satisfy such a predicate. Almost true!
I think you're correct that r1 and r2 cannot both be true for the same set of arguments (or any sets of arguments with the same first argument s). But the constraint you specify uses r1[s,s',m,m'] and r2[s,s',m,m'] in the antecedent of a conditional. Before you go any further, stop and think: What is the truth value of a conditional if the antecedent is false?
If you are having trouble seeing what is going on, try examining the instances of your model in which the antecedent of your conditional is true for all pairs of States and Systems. Concretely, add the following to your model and look at the instances it produces.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
}
run antecedent
It took me a minute or two before I understood what I was seeing; if it takes you longer than a few minutes, you might try the following variant definition of antecedent and see if it enlightens you.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
some State
some System
}
You are not the first user of first-order logic to have been taken by surprise when a conditional statement in your model turned out to be vacuously true when you expected it to be false. You won't be the last.
Sorry, this may seem similar to an earlier question but I am still a little confused. Here is the same code I am using as an example:
type Pig = String
type Lion = String
type Feed = [(Char,Char)]
type Visitors = [(Char,Char)]
type Costs = (Int,Int,Int)
data AnimalHome = Farm Pig Pig Pig Feed | Zoo Lion Lion Lion Feed Visitors
orders :: Char -> AnimalHome -> Costs -> Char
orders stuff (Farm p1 p2 p3 feed) (cost1,cost2,cost3) = some code here
But this time I want to execute different functions if the costs are different i.e. (1,3,9) executes a different equation to (0,0,16) etc.
You can adapt the answers to your previos similar questions for this case. Remember that a 3-tuple or triple (i.e. your type Costs) is just another data type. If there were no tuples in Haskell, you could write:
data Triple a b c = Triple a b c
and it would behave exactly as 3-tuples do! The only difference is that Hakell supports a more convenient syntax both for tuple expressions and tuple patterns.
Now for Patterns in general: Simplifying a bit, there are basicall 3 possibilities to write them:
a literal (suitable only for data types that support this, like String, Int, etc.), matches only that value.
a variable, matches any value
a data constructor, applied to patterns. Matches values constructed with that data constructor where the subpatterns match.
Turns out that you already wrote correct patterns in your question:
i.e. (1,3,9) executes a different equation to (0,0,16)
hence
orders stuff (Farm p1 p2 p3 feed) (1,3,9) = some code here
orders stuff (Farm p1 p2 p3 feed) (0,0,16) = some other code here
It probably would help us to help you if we could understand what your specific issues with pattern matching is. i.e. why you couldn't just try to come up with that yourself, as it feels quite natural, does it not?
If you really mean to use different functions with different integers, it's fine to use pattern matching
orders stuff (Farm p1 p2 p3 feed) (1,3,9) = -- one thing
orders stuff (Farm p1 p2 p3 feed) (0,0,16) = -- another thing
but I'd only really use that with 0, not other values. Really what you're after is called guards:
orders stuff (Farm p1 p2 p3 feed) (a,b,c)
| a == 0 && b == 0 = -- one thing
| a*b^2=c = -- another thing
| b < 0 = -- a third thing
and each condition is checked in turn - only the first true condition gets to run its code.
I am writing a simple Alloy code but I cannot understand how can I say AT MOST one A has associate with p.D (so AT MOST would be One or Zero). So I wrote the below code but the assertion presents no counter-example with an instance of P1 without D. Could you help me how can I define my fact in terms of having AT MOST one instance for p.D where I can see a counter example that p has no connection for its D.
abstract sig A {}
sig A1,A2,A3 extends A{}
abstract sig P {}
sig P1 extends P {D: A}
fact
{
all p: P1 | lone (p.D & A)
}
assert asr
{no p: P1 | no (p.D & A)}
check asr for 5
Your specification (introduction of sig P1) says that for each p in P1 is always related by d to exactly one a in A. Your fact is redundant ("0 or 1" is implied by "always 1").
You could declare "sig P1 extends P (D : lone A}". (The fact would still be redundant.)
Also note that the "& A"s in your fact and assertion are redundant.
You might have meant the fact to be
fact {lone P1.D}
which says that all those instances of P1 which are related to an A are related to the same A.