0

How to assign variable in Alloy?

Sig ClassA{
    variable_1: String,
    variable_2: Int
}

Sig ClassB{
    variable_1: String,
    variable_2: Int
}

pred isLess[a:ClassA,b:ClassB]{
    a.variable_2 < b.variable_2
}

assert integrityTest{
    all a:ClassA,b:ClassB| isLess[a,b]

}

Now I want to check counterexample of variables when I assign some bigger value in a.variable_2 than b.variable_2. But I am not sure how to assign variable in Alloy. Only thing I came up with is following but it is not working-

pred assignValue[a:ClassA]{
    a.variable_2 = Int[4]  
}

However, I believe it will only check the equality with 4 and return as false. It has nothing to do with the assignment. So my question is how should I produce counterexample when a.variable_2>b.variable_2

And How can I use Enum of Int in alloy? Like- Enum MetricValue {1,2,3,4,5} to assign a.variable 1.

EDIT I am still having trouble finding the counterexample, even though I can find one by manually checking when I toggle the value of variable_2 of ca and cb.

 sig ClassA{ 
    variable_1: String, 
    variable_2 = Int 
 } 

 sig CA extends ClassA{}{ 
    variable_2 = 1 
 } 
 sig ClassB{ 
    variable_1: String,
    variable_2 = Int 
 } 
 sig CB extends ClassB{}{ 
    variable_2 = 4 
 }

 pred checkAllConstraint [ca: ClassA, cb: ClassB] { 
    ca.variable_2 > cb.variable_2 } 

  assert checkAll{ 
    all ca: ClassA, cb: ClassB | checkAllConstraint[ca,cb] 
  } 
  check checkAll for 15
Loïc Gammaitoni
  • 4,173
  • 16
  • 39
faysal
  • 162
  • 2
  • 14
  • Well, your syntax is wrong (it is sig not Sig) so it seems you have not run this in Alloy? I also would suggest to absolutely minimize a question before you put it on Stackoverflow. Last, I think you miss some of the very basics of Alloy. It is not a programming language but a specification language so you specify constraints, not destructive operations like assignments. In Alloy you would make a _trace_ that shows consecutive assignments to a state sig. In Daniel Jacksons book he uses the `Time` concept for this. – Peter Kriens Mar 13 '19 at 10:39
  • I don't believe, judging from the question, that he's interested in temporal properties. He seems to just want to constraints some fields to some values. assignment is certainly the wrong term given the declarative nature of Alloy, yet the question can still be answered ^^ – Loïc Gammaitoni Mar 14 '19 at 06:51

1 Answers1

1

You can restrain a field to a single value through facts. In your case, signature facts come handy.

It will look like this:

sig ClassA{
  variable_1: String,
  variable_2: Int
}{
    variable_1="hello world"
    variable_2=4
}

To bound a field to one value amongst a set, you can use the "in" keyword instead of "=" as follows:

sig ClassA{
variable_1: String,
variable_2: Int
}{
    variable_1 in ("hello" + "world")
    variable_2 in (1+2+3+4)  
}

Note that in Alloy + is a UNION operator. It doesn't sum nor concatenate as you might expect.

EDIT It doesn't work for 2 reasons:

  • you wrote : variable_2 = Int instead of variable_2: Int. By doing so, no valid instance contains atoms typed by CA or CB, because e.g. ClassA.variable2 is constrained to be the set of all integers and CA.variable2 is constrained to be 1
  • no String atom is defined. That's one of Alloy's weird part. If you want to use Strings in your model, you need to have string litterals somewhere specified, e.g. in a fact.

Here's your model, corrected:

sig ClassA{ 
    variable_1: String, 
    variable_2 : Int 
 } 

 sig CA extends ClassA{}{ 
    variable_2 = 1 
 } 
 sig ClassB{ 
    variable_1: String,
    variable_2 : Int 
 } 
 sig CB extends ClassB{}{ 
    variable_2 = 4 
 }

 pred checkAllConstraint [ca: ClassA, cb: ClassB] { 
    ca.variable_2 > cb.variable_2 } 

  assert checkAll{ 
    all ca: ClassA, cb: ClassB | checkAllConstraint[ca,cb] 
  } 
  check checkAll for 15

fact { String in ("test"+"test2"+"test3"+"test4")}

If you still have questions, please create a new one.

-

Loïc Gammaitoni
  • 4,173
  • 16
  • 39
  • Thanks for your suggestion. However, I am still having trouble finding the counterexample, even though I can find one by manually checking when I toggle the value of variable_2 of ca and cb. `sig ClassA{ variable_1: String, variable_2 = Int } sig CA extends ClassA{ }{ variable_2 = 1 } sig ClassB{ variable_1: String, variable_2 = Int } sig CB extends ClassB{} { variable_2 = 4 }pred checkAllConstraint [ca: ClassA, cb: ClassB] { ca.variable_2 > cb.variable_2 } assert checkAll{ all ca: ClassA, cb: ClassB | checkAllConstraint[ca,cb] } check checkAll for 15` – faysal Mar 15 '19 at 02:13
  • Thanks a lot for your help. It works for me. Btw, I have one small question. Where did you find that you can assign variable in a fact in alloy (the way you suggested). I am asking this because I read some tutorials and book in the internet but didnt find any solution like you mentioned. – faysal Mar 15 '19 at 21:02
  • Facts are here to describe invariants. What you mistakenly call variable assignment is actually the specification of an invariant: "In all my instances I want variable_2 to be equals to 4". You could read more about facts and alloy in general on this website: http://blackmesatech.com/2013/07/alloy/slides/s3.design.html – Loïc Gammaitoni Mar 17 '19 at 10:24
  • can we assign a variable from the predicate? – faysal Apr 14 '19 at 23:15