No instance found for simple List example - alloy

I'm studying Alloy and I'm trying to specify a general simple array list. My specification is based on the first examples of Alloy's Book and Online Tutorial. I'm just exploring the language by trying to test its basic features and what I want to do is really simple, but isn't working and I don't know why because it is very similar to the examples. This is my specification:
module FileSystem/Lists[A]
open util/ordering[List]
sig List {
content: Int ->one A,
size: Int
}{
size = #content
all i : Int, e : A | i -> e in content => i >= 0
all i : Int | i in content.univ => i >= 0 and i < size
}
pred init [l: List] { (no l.content) && l.size = 0}
fact traces {
init[first]
all l: List-last |
let l' = l.next |
some e: A |
add [l, l', e]
}
pred add [l, l': List, e: A] {
l'.content = l.content + (l.size -> e)
l'.size = l.size + 1
}
run add for 3 but 2 List
assert listSize {
all l: List - last, l': l.next, e: A |
add[l,l',e] => l'.size = (l.size + 1) and
e in univ.(l'.content)
}
check listSize for 10
When I execute run add, the Alloy Analyzer says: No instance found. add my be inconsistent. But when I run check listSize it don't found any counterexample, suggesting that listSize is valid. Someone knows why the Alloy Analyzer can't found one instance for add? I try to change the number of elements, but don't worked. I think that this module is really simple, but I really don't know why I'm having this problems.

Here's one thing I noticed. Your decl for content
content: Int ->one A,
says every int is mapped, and then you add a constraint saying only some ints are mapped
all i : Int, e : A | i -> e in content => i >= 0
which is an inconsistency.
A more general point: make structures with relations (that is, as graphs) not using using integers as indexes, whenever you can. Because Alloy is bounded, integers are quite subtle.

Related

Does GHC optimize functions that pattern match against a large number of 0 argument data constructors? [duplicate]

Let's say we have the following Haskell:
data T = T0 | T1 | T2 | ... | TN
toInt :: T -> Int
toInt t = case t of
T0 -> 0
T1 -> 1
T2 -> 2
...
TN -> N
What algorithm is used to perform the pattern match here? I see two options:
(1) Linear search, something like
if (t.tag == T0) { ... }
else if (t.tag == T1) { ... }
else ...
(2) Binary search, which would be sensible in this specific task: searching for t.tag in the set {TO...T1023}. However, where pattern matching in general has many other capabilities and generalizations, this may not be used.
Compiling with GHC, what algorithm is used, and what is the time complexity in terms of N, for pattern matching on t in toInt?
A jump table is used, making the pattern-match a constant time operation.
Unfortunately I'm unable to find an up-to-date citation for this, although this page mentions the implementation of Cmm-level switch statements as jump tables, and this old tagging design document uses a case on a Bool as an example, producing a jump table.

Alloy - Count atoms used by other atoms

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

specifying properties of relations in alloy

I am trying to express certain mathematical properties of relations in Alloy, but I am not sure if I have the right approach yet, as I am just a beginner. Would appreciate any insights from the community of experts out there!
Specifying the fact that domain of a relation as singleton. e.g. Is the following a reasonable and correct way to do that?
pred SingletonDomain(r: univ->univ) {
one ~r
}
sig S2 {}
sig S1 {
child: set S2
}
fact {
SingletonDomain [child]
}
or should it be something like the following
pred SingletonDomain (r: univ->univ) {
#S2.~r = 1
}
This is not very modular since the use of S2 is very specific to the particular signature.
Specifying the fact that a relation is a total order. At the moment I am using the following, basically I am simulating xor
pred total[r: univ->univ] {
all disj e, e': Event | (e.r = e' and e'.r != e) or (e.r != e' and e'.r = e)
}
Thanks
To specify the fact that the domain of a given relation is a singleton, your first attempt is really close to do the trick. The only problem is that one ~r enforces the inverse of the r relation (and thus the r relation itself) to be composed of a single tuple. This is not what you want to express.
What you want to express is that all elements in the range of the r relation have the same (so only one) image through its inverse relation '.
You should thus write the following predicate :
pred SingletonDomain(r: univ->univ) {
one univ.~r
}
For your second question, your predicate doesn't handle cases were e -> e' -> e '' -> e. To handle those, you can use transitive closure.

Summing over a set of util/natural numbers in alloy4

I found myself trying to sum a set of naturals. I was puzzled by the following behavior when running a simple model.
(assume the following code is in a copy of util/natural, so ord is imported)
//sums the values in a set of naturals
fun setsum[nums : set Natural] : lone Natural {
{n : Natural | #ord/prevs[n] = (sum x : nums | #ord/prevs[x])}
}
then, in a module importing my copy of util/natural:
private open mynatural as nat
let two = nat/add[nat/One, nat/One]
let three = nat/add[two, nat/One]
let four = nat/add[two, two]
let five = nat/add[four,nat/One]
pred showExpectSum10 {
some x : Natural | x in setsum[{n : Natural | nat/lt[n, five]}]
}
//run showExpectSum10 for 15 //result is 10, as expected
//run showExpectSum10 for 1 but 20 Natural //result is 10 as expected
run showExpectSum10 for 1 but 40 Natural //result is 26 somehow.
Why does changing the scope of Natural affect the result this way?
It seems you just need to disable overflows ("Options -> Forbid Overflows: Yes"), and then it should work as expected. Every time integer arithmetic is used and overflows are allowed (which is the default setting) it possible to get spurious counterexamples (i.e., invalid instances) due to the default "wraparound" semantics of arithmetic operations in Alloy.

Haskell Typeclass Inspection

I would like to use haskell to implement a game, and would like to use a system of type classes to implement the item system. It would work something like this:
data Wood = Wood Int
instance Item Wood where
image a = "wood.png"
displayName a = "Wood"
instance Flammable Wood where
burn (Wood health) | health' <= 0 = Ash
| otherwise = Wood health'
where health' = health - 100
where the Item and Flammable classes are something like this:
class Item a where
image :: a -> String
displayName :: a -> String
class Flammable a where
burn :: (Item b) => a -> b
To do this, I would need a way to detect whether a value is an instance of a type class.
The Data.Data module gives a similar functionality so that leads me to believe that this is possible.
Type classes are probably the wrong way to go here. Consider using plain algebraic data types instead, for example:
data Item = Wood Int | Ash
image Wood = "wood.png"
image Ash = ...
displayName Wood = "Wood"
displayName Ash = "Ash"
burn :: Item -> Maybe Item
burn (Wood health) | health' <= 0 = Just Ash
| otherwise = Just (Wood health')
where health' = health - 100
burn _ = Nothing -- Not flammable
If this makes it too hard to add new items, you can instead encode the operations in the data type itself.
data Item = Item { image :: String, displayName :: String, burn :: Maybe Item }
ash :: Item
ash = Item { image = "...", displayName = "Ash", burn :: Nothing }
wood :: Int -> Item
wood health = Item { image = "wood.png", displayName = "Wood", burn = Just burned }
where burned | health' <= 0 = ash
| otherwise = wood health'
health' = health - 100
However, this makes it harder to add new functions. The problem of doing both at the same time is known as the expression problem. There is a nice lecture on Channel 9 by Dr. Ralf Lämmel where he explains this problem more in depth and discusses various non-solutions, well worth the watch if you have time.
There are approaches to solving it, but they are considerably more complex than the two designs I've illustrated, so I recommend using one of those if it fits your needs, and not worrying about the expression problem unless you have to.
Here's the problem:
burn :: (Item b) => a -> b
What this means is that the result value of burn must be polymorphic. It must be able to fill any hole for any instance of Item.
Now, it's quite apparent you're trying to write something like this (in imaginary OO language with interfaces and subclassing):
Interface Item {
String getImage();
String getDisplayName();
}
Interface Flammable {
Item burn();
}
In this sort of code, you're saying that burn will produce some item, without any guarantees about what kind of item it is. This is the difference between "for all" and "there exists". What you wanted to express in the Haskell code was "there exists", but what you actually expressed was "for all".
Now if you're really sure you want to do "there exists" functionality, you can take a look at using Existential Types. But beware. If you are planning on writing code like this:
if (foo instanceof Flammable) {
...
}
Then you are almost certainly doing it wrong, and will run into much pain and agony. Instead consider hammar's suggested alternatives.

Resources