简体   繁体   中英

Value assignment in Alloy and use of Enum

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

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 eg 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, eg 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.

-

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM