transitive closure in alloy - alloy

Can any one here explains how the transitive closure operator works in Alloy in terms of the matrix. I mean what's translation rule for translating closure operator into actual matrix operation.

To compute transitive closure, Kodkod uses iterative squaring.
In a nutshell, if you have a binary relation r (which directly translates to a 2-dimensional boolean matrix), transitive closure of r can be computed iteratively as
r1 = r or (r . r)
r2 = r1 or (r1 . r1)
r3 = r1 or (r2 . r2)
...
^r = rn = rn-1 or (rn-1 . rn-1)
The question is when do we stop, i.e., what should n be. Since everything is bounded, Kodkod statically knows the maximum number of rows in r, and it should be intuitively clear that if n is set to be that number of rows, the algorithm will produce a semantically correct translation. However, even n/2 is enough (since we are squaring the matrix every time), which is the actual number Kodkod uses.

Related

Apply function to all pairs efficiently

I need a second order function pairApply that applies a binary function f to all unique pairs of a list-like structure and then combines them somehow. An example / sketch:
pairApply (+) f [a, b, c] = f a b + f a c + f b c
Some research leads me to believe that Data.Vector.Unboxed probably will have good performance (I will also need fast access to specific elements); also it necessary for Statistics.Sample, which would come in handy further down the line.
With this in mind I have the following, which almost compiles:
import qualified Data.Vector.Unboxed as U      
pairElement :: (U.Unbox a, U.Unbox b)    
=> (U.Vector a)                    
  -> (a -> a -> b)                   
  -> Int                             
-> a                               
 -> (U.Vector b)                    
pairElement v f idx el =
U.map (f el) $ U.drop (idx + 1) v            
pairUp :: (U.Unbox a, U.Unbox b)   
=> (a -> a -> b)                        
 -> (U.Vector a)                         
-> (U.Vector (U.Vector b))
pairUp f v = U.imap (pairElement v f) v 
pairApply :: (U.Unbox a, U.Unbox b)
=> (b -> b -> b)                     
-> b                                 
 -> (a -> a -> b)                     
-> (U.Vector a)                      
 -> b
pairApply combine neutral f v =
folder $ U.map folder (pairUp f v) where
folder = U.foldl combine neutral
The reason this doesn't compile is that there is no Unboxed instance of a U.Vector (U.Vector a)). I have been able to create new unboxed instances in other cases using Data.Vector.Unboxed.Deriving, but I'm not sure it would be so easy in this case (transform it to a tuple pair where the first element is all the inner vectors concatenated and the second is the length of the vectors, to know how to unpack?)
My question can be stated in two parts:
Does the above implementation make sense at all or is there some quick library function magic etc that could do it much easier?
If so, is there a better way to make an unboxed vector of vectors than the one sketched above?
Note that I'm aware that foldl is probably not the best choice; once I've got the implementation sorted I plan to benchmark with a few different folds.
There is no way to define a classical instance for Unbox (U.Vector b), because that would require preallocating a memory area in which each element (i.e. each subvector!) has the same fixed amount of space. But in general, each of them may be arbitrarily big, so that's not feasible at all.
It might in principle be possible to define that instance by storing only a flattened form of the nested vector plus an extra array of indices (where each subvector starts). I once briefly gave this a try; it actually seems somewhat promising as far as immutable vectors are concerned, but a G.Vector instance also requires a mutable implementation, and that's hopeless for such an approach (because any mutation that changes the number of elements in one subvector would require shifting everything behind it).
Usually, it's just not worth it, because if the individual element vectors aren't very small the overhead of boxing them won't matter, i.e. often it makes sense to use B.Vector (U.Vector b).
For your application however, I would not do that at all – there's no need to ever wrap the upper element-choices in a single triangular array. (And it would be really bad for performance to do that, because it make the algorithm take O (n²) memory rather than O (n) which is all that's needed.)
I would just do the following:
pairApply combine neutral f v
= U.ifoldl' (\acc i p -> U.foldl' (\acc' q -> combine acc' $ f p q)
acc
(U.drop (i+1) v) )
neutral v
This corresponds pretty much to the obvious nested-loops imperative implementation
pairApply(combine, b, f, v):
for(i in 0..length(v)-1):
for(j in i+1..length(v)-1):
b = combine(b, f(v[i], v[j]);
return b;
My answer is basically the same as leftaroundabout's nested-loops imperative implementation:
pairApply :: (Int -> Int -> Int) -> Vector Int -> Int
pairApply f v = foldl' (+) 0 [f (v ! i) (v ! j) | i <- [0..(n-1)], j <- [(i+1)..(n-1)]]
where n = length v
As far as I know, I do not see any performance issue with this implementation.
Non-polymorphic for simplicity.

Denotational semantics, proving that fixed point iteration results in the least fixed point

I'm working through the Haskell wikibook section on denotational semantics and I'm kind of stuck on this exercise:
Prove that the fixed point obtained by fixed point iteration starting
with is also the least one, that it is smaller than any other
fixed point. (Hint: is the least element of our cpo and g is
monotone).
Where the following statements define the core of the concepts leading up to the exercise (I think):
where f is the factorial function and is shown to be the fixed-point of g, given that g is continuous.
I think I basically understand the part where it is shown that g(f) = f but I don't really know what to make of the exercise. From what I understand, the factorial function f is the least-fixed point (with least based on the operator) but it's not at all clear to me what it means (intuitively) to compare functions with , let alone how I would find fixed points other than the least-fixed point shown in the example.
I understand that is less than everything else, and I understand that since g(x) is monotonic, if I apply it to two things, where one is less than the other, the results will still obey this ordering.
I think I would start the proof with taking some function f' and assuming . If that is the case, through the monotonic property of g I can show that . If I can then show that necessarily g(f') = g(f) or f' = f I think the proof is complete but I have no idea how to show that.
Let x be the sup/least upper bound of the sequence bot, g(bot), g(g(bot)), .... Let y be any fixed point of g (monotonic). We want to prove that x <= y.
By induction on the number of iterations, it's easy to see that every element in the sequence is <= y. Indeed, it trivially holds for bot, and if z is <= y by monotonicity we get g(z) <= g(y) = y.
So, y is an upper bound of the sequence. But x is the least, so x <= y. QED.

what's the relationship between Monad and single threaded?

When I study Monod I want to know what path is best for understanding Haskell's Monad. Many people such as Bartosz Milewski proposed that Monads for functional programming is the best material. After reading a part of this paper I got the same feeling, but in 4.2 Array transforms, I have no idea how to understand the summary about Monad as I miss some foundation in the bottom part of page 16:
"Making M into an abstract data type guarantees that single threading is
preserved, and hence it is safe to implement assignment with an in-place update.
The use of data abstraction is essential for this purpose. Otherwise, one could
write programs such as (\x -> (assign i v x ; assign i w x )) that violate the single threading property."
I don't know why Philip Wadler discuss single threading here? data M a = State -> (a, State) must be very important for guaranteeing single threading, why?
For that I implement the code of this section 4.2 Array transforms, where I assume that my Array is like Arr [("ok", 0), ("no", 1)], and index is string, value is Int:
type M a = State -> (a, State)
data Arr = Arr [(Id, Val)] deriving (Show)
type State = Arr
type Id = String
type Val = Int
type Ix = Id
update ix val arr = updateNew ix val arr (Arr [])
where updateNew ix val (Arr (x:xs)) (Arr newArr) =
case (fst x) == ix of
True -> Arr (newArr ++ ((ix,val):xs))
False -> updateNew ix val (Arr xs) (Arr (newArr ++ [x]))
assign :: Ix -> Val -> M ()
assign i v = \x -> ((), update i v x)
But this is not helpful for me to understand the above summary. I hope one enthusiastic person to explain more about it!
In Haskell, something like [("ok", 0), ("no", 1)] is not an array*, but rather a list. Haskell lists are immutable, so you don't even have to think about them changing. Arrays are another story. There are actually two very different things, both called arrays: immutable arrays and mutable arrays.
Immutable arrays are just alternative representations of certain sorts of functions along with some information about their domains.
Wadler is discussing mutable arrays, which can actually be changed. We don't actually handle these arrays directly; rather, we deal with values that serve as pointers to them. In languages like ML, Java, C, etc., you can "follow" a pointer any time you have one to access or modify the value(s) it points to. But that would completely break Haskell's referential transparency, which is critical to both understanding and optimizing it.
So what we do instead is encapsulate the changes to an array within an abstract monad. All sorts of things are going on under the hood that break the rules, but what gets exposed to you, the programmer, is guaranteed to make sense. There are actually two monads that can support mutable arrays in GHC: IO and ST s. ST s lets you, in a pure function, make an array, mutate it all sorts of ways, and then produce a pure result. IO, on the other hand, lets you intermix array creation and modifications with other IO actions.
* In GHC, it might be an array, because GHC offers an extension called OverloadedLists, but even in GHC it's very unlikely to be an array.

ghci compiler optimization: calling a function with same parameter twice

In the simple code below, part of the definition of a function that deletes an element from a binary search tree:
deleteB x (Node n l r) | x == n = Node (leastB r) l (deleteB (leastB r) r)
does the compiler optimize the code so that it calls (least B r) only once as if it were:
deleteB x (Node n l r) | x == n = Node k l (deleteB k r)
where k = leastB r
?
In other words, is the compiler able to understand that since parameter r isn't changed within the body of the function deleteB, the result of the call of the same function (leastB) on it can't give different results, hence it is useless to compute it twice?
More generally, how would I be able to understand if the compiler does this optimization or not in case amazing stackoverflow did not exist? thanks
If you want to know what GHC "really did", you want to look at the "Core" output.
GHC takes your Haskell source code, which is extremely high-level, and transforms it into a sequence of lower and lower-level languages:
Haskell ⇒ Core ⇒ STG ⇒ C−− ⇒ assembly language ⇒ machine code
Almost all of the high-level optimisations happen in Core. The one you're asking about is basically "common subexpression elimination" (CSE). If you think about it, this is a time / space tradeoff; by saving the previous result, you're using less CPU time, but also using more RAM. If the result you're trying to store is tiny (i.e., an integer), this can be worth it. If the result is huge (i.e., the entire contents of that 17GB text file you just loaded), this is probably a Very Bad Idea.
As I understand it (⇒ not very well!), GHC tends not to do CSE. But if you want to know for sure, in your specific case, you want to look at the Core that your program has actually been compiled into. I believe the switch you want is --ddump-prep.
http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/options-debugging.html
GHC does not perform this optimization because it is not always an optimization space-wise.
For instance, consider
n = 1000000
x = (length $ map succ [1..n], length $ map pred [1..n])
On a lazy language such as Haskell, one would expect this to run in constant space. Indeed, the list generating expression [1..n] should lazily produce an element at a time, which would be affected by succ/pred because of the maps, and then counted by length. (Even better, succ and pred are not computed at all since length does not force the list elements). After this, the produced element can be garbage collected, and the list generator can produce the next element, and so on. In real implementations, one would not expect every single element to be garbage collected immediately, but if the garbage collector is good, only a constant amount of them should be in memory at any time.
By comparison, the "optimized" code
n = 1000000
l = [1..n]
x = (length $ map succ l, length $ map pred l)
does not allow to garbage collect the elements of l until both components of x are evaluated. So, while it produces the list only once, it uses O(n) words of memory to store the full list. This is likely to lead to a lower performance than the unoptimized code.

Haskell: Prefer pattern-matching or member access?

Suppose I have a Vector datatype defined as follows:
data Vector = Vector { x :: Double
, y :: Double
, z :: Double
}
Would it be more usual to define functions against it using member access:
vecAddA v w
= Vector (x v + x w)
(y v + y w)
(z v + z w)
Or using pattern-matching:
vecAddB (Vector vx vy vz) (Vector wx wy wz)
= Vector (vx + wx)
(vy + wy)
(vz + wz)
(Apologies if I've got any of the terminology incorrect).
I would normally use pattern matching, especially since you're using all of the constructor's arguments and there aren't a lot of them. Also, In this example it's not an issue, but consider the following:
data Foo = A {a :: Int} | B {b :: String}
fun x = a x + 1
If you use pattern matching to do work on the Foo type, you're safe; it's not possible to access a member that doesn't exist. If you use accessor functions on the other hand, some operations such as calling fun (B "hi!") here will result in a runtime error.
EDIT: while it's of course quite possible to forget to match on some constructor, pattern matching makes it pretty explicit that what happens depends on what constructor is used (you can also tell the compiler to detect and warn you about incomplete patterns) whereas the use of a function hints more that any constructor goes, IMO.
Accessors are best saved for cases when you want to get at just one or a few of the constructor's (potentially many) arguments and you know that it's safe to use them (no risk of using an accessor on the wrong constructor, as in the example.)
Another minor "real world" argument: In general, it isn't a good idea to have such short record entry names, as short names like x and y often end up being used for local variables.
So the "fair" comparison here would be:
vecAddA v w
= Vector (vecX v + vecX w) (vecY v + vecY w) (vecZ v + vecZ w)
vecAddB (Vector vx vy vz) (Vector wx wy wz)
= Vector (vx + wx) (vy + wy) (vz + wz)
I think pattern matching wins out in most cases of this type. Some notable exceptions:
You only need to access (or change!) one or two fields in a larger record
You want to remain flexible to change the record later, such as add more fields.
This is an aesthetic preference since the two are semantically equivalent. Well, I suppose a in a naive compiler the first one would be slower because of the function calls, but I have a hard time believing that would not be optimized away in real life.
Still, with only three elements in the record, since you're using all three anyway and there is presumably some significance to their order, I would use the second one. A second (albeit weaker) argument is that this way you're using the order for both composition and decomposition, rather than a mixture of order and field access.
(Alert, may be wrong. I am still a Haskell newbie, but here's my understanding)
One thing that other people have not mentioned is that pattern matching will make the function "strict" in its argument. (http://www.haskell.org/haskellwiki/Lazy_vs._non-strict)
To choose which pattern to use, the program must reduce the argument to WHNF before calling the function, whereas using the record-syntax accessor function would evaluate the argument inside the function.
I can't really give any concrete examples (still being a newbie) but this can have performance implications where huge piles of "thunks" can build up in recursive, non-strict functions. (That is to mean, for simple functions like extracting values, there should be no performance difference).
(Concrete examples very much welcome)
In short
f (Just x) = x
is actually (using BangPatterns)
f !jx = fromJust jx
Edit: The above is not a good example of strictness, because both are actually strict from definition (f bottom = bottom), just to illustrate what I meant from the performance side.
As kizzx2 pointed out, there is a subtle difference in strictness between vecAddA and vecAddB
vecAddA ⊥ ⊥ = Vector ⊥ ⊥ ⊥
vecAddB ⊥ ⊥ = ⊥
To get the same semantics when using pattern matching, one would have to use irrefutable patterns.
vecAddB' ~(Vector vx vy vz) ~(Vector wx wy wz)
= Vector (vx + wx)
(vy + wy)
(vz + wz)
However, in this case, the fields of Vector should probably be strict to begin with for efficiency:
data Vector = Vector { x :: !Double
, y :: !Double
, z :: !Double
}
With strict fields, vecAddA and vecAddB are semantically equivalent.
Hackage package vect solves both these problems by allowing matching like f (Vec3 x y z) and indexing like:
get1 :: Vec3 -> Float
get1 v = _1 v
Look up HasCoordinates class.
http://hackage.haskell.org/packages/archive/vect/0.4.7/doc/html/Data-Vect-Float-Base.html

Resources