Alloy4.2 - Ternary relation to a binary relation - alloy

So I'm trying to write a function that takes a set of ternary relations and one of the middle elements which returns the set of relations where the element matches, but doesn't contain itself. (We already know what it is)
So something like this:
// addr gives us: {Book -> Name -> Addr}
fun [n:Name] : Set Book -> Addr {
//return {b->a} where {b->n->a}
}
With joins and domain restrictions, I've only been able to manage to get the binary relations: {Book -> Name} and {Name -> Addr}. I'm not sure how I would splice these together as the Name is constant, so you can't tell the difference.
Is it possible to do this with a function, or do I need something else?
I'm an absolute beginner at this, and it seems fairly simple in a normal procedural language. However, I can't find very good documentation and it looks to me I've just got completely the wrong end of the stick on terms of how functions work in this.

Or even more simply:
fun [n:Name]: Book -> Addr {
{b:Book,a:Addr | b->n->a in addr}
}
However, your use of the term "set of relations" and the keyword "set" in your function declaration makes me wonder if you mean something different. Note that this function returns a set of tuples, not a set of relations.

You can probably calculate that with a definition by comprehension:
fun [n:Name]: Book -> Addr {
{b:Book,a:Addr | b in (addr.a).n }
}

Related

A meaningful field name for the ternary relation between program, data, and result?

I have a signature for representing software programs:
sig Program {
???: Data -> Result
}
Each program maps input data to output result. So, there is a ternary relation (Program -> Data -> Result).
Notice the question marks for the field name. What field name do you suggest?
The name IO seems nice:
sig Program {
IO: Data -> Result
}
Then I can write elegant expressions such as:
all p: Program | p.IO ...
However, the name IO is meaningful only for (Data -> Result) not (Program -> Data -> Result).
I am stuck. What do you suggest?
IMHO, fields' names are most of the time contextual to the signature they are declared in, and that's really a fine thing.
If you look at a random sample module in Alloy, (e.g. module examples/puzzle/farmer), you'll see that it's not always that fields have meaning outside of their respective signatures:
sig State {
near: set Object,
far: set Object
}
Here, near and far don't really convey hints on their "temporal" nature.
Long story short, I'd stick to io for conciseness sake.
Indeed, I prefer the names of :
fiels, facts, preds, asserts, parameters, .. to be in lowercase
signatures to be Capitalized
enumeration (outer let), and singleton signatures to be in UPPERCASE

Infinite loop while updating record [duplicate]

I want to update a record syntax with a change in one field so i did something like:
let rec = rec{field = 1}
But I've noticed that i can't print rec anymore, means the compiler seems to get into an infinite loop when i try. so i have tried doing:
let a = 1 -- prints OK
let a = a -- now i can't print a (also stuck in a loop)
So i can't do let a = a with any type, but i don't understand why, and how should i resolve this issue.
BTW: while doing:
let b = a {...record changes..}
let a = b
works, but seems redundant.
The issue you're running into is that all let and where bindings in Haskell are recursive by default. So when you write
let rec = rec { ... }
it tries to define a circular data type that will loop forever when you try to evaluate it (just like let a = a).
There's no real way around this—it's a tradeoff in the language. It makes recursive functions (and even plain values) easier to write with less noise, but also means you can't easily redefine a a bunch of times in terms of itself.
The only thing you can really do is give your values different names—rec and rec' would be a common way to do this.
To be fair to Haskell, recursive functions and even recursive values come up quite often. Code like
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
can be really nice once you get the hang of it, and not having to explicitly mark this definition as recursive (like you'd have to do in, say, OCaml) is a definite upside.
You never need to update a variable : you can always make another variable with the new value. In your case let rec' = rec{field = 1}.
Maybe you worry about performance and the value being unnecessarily copied. That's the compiler's job, not yours : even if you declare 2 variables in your code, the compiler should only make one in memory and update it in place.
Now there are times when the code is so complex that the compiler fails to optimize. You can tell by inspecting the intermediate core language, or even the final assembly. Profile first to know what functions are slow : if it's just an extra Int or Double, you don't care.
If you do find a function that the compiler failed to optimize and that takes too much time, then you can rewrite it to handle the memory yourself. You will then use things like unboxed vectors, IO and ST monad, or even language extensions to access the native machine-level types.
First of all, Haskell does not allow "copying" data to itself, which in the normal sense, means the data is mutable. In Haskell you don't have mutable "variable"s, so you will not be able to modify the value a given variable presents.
All you have did, is define a new variable which have the same name of its previous version. But, to do this properly, you have to refer to the old variable, not the newly defined one. So your original definition
let rec = rec { field=1 }
is a recursive definition, the name rec refer to itself. But what you intended to do, is to refer to the rec defined early on.
So this is a name conflict.
Haskell have some machenism to work around this. One is your "temporary renaming".
For the original example this looks like
let rec' = rec
let rec = rec' { field=1 }
This looks like your given solution. But remember this is only available in a command line environment. If you try to use this in a function, you may have to write
let rec' = rec in let rec = rec' { field=1 } in ...
Here is another workaround, which might be useful when rec is belong to another module (say "MyModule"):
let rec = MyModule.rec { field=1 }

Haskell: let statement, copy data type to itself with/without modification not working

I want to update a record syntax with a change in one field so i did something like:
let rec = rec{field = 1}
But I've noticed that i can't print rec anymore, means the compiler seems to get into an infinite loop when i try. so i have tried doing:
let a = 1 -- prints OK
let a = a -- now i can't print a (also stuck in a loop)
So i can't do let a = a with any type, but i don't understand why, and how should i resolve this issue.
BTW: while doing:
let b = a {...record changes..}
let a = b
works, but seems redundant.
The issue you're running into is that all let and where bindings in Haskell are recursive by default. So when you write
let rec = rec { ... }
it tries to define a circular data type that will loop forever when you try to evaluate it (just like let a = a).
There's no real way around this—it's a tradeoff in the language. It makes recursive functions (and even plain values) easier to write with less noise, but also means you can't easily redefine a a bunch of times in terms of itself.
The only thing you can really do is give your values different names—rec and rec' would be a common way to do this.
To be fair to Haskell, recursive functions and even recursive values come up quite often. Code like
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
can be really nice once you get the hang of it, and not having to explicitly mark this definition as recursive (like you'd have to do in, say, OCaml) is a definite upside.
You never need to update a variable : you can always make another variable with the new value. In your case let rec' = rec{field = 1}.
Maybe you worry about performance and the value being unnecessarily copied. That's the compiler's job, not yours : even if you declare 2 variables in your code, the compiler should only make one in memory and update it in place.
Now there are times when the code is so complex that the compiler fails to optimize. You can tell by inspecting the intermediate core language, or even the final assembly. Profile first to know what functions are slow : if it's just an extra Int or Double, you don't care.
If you do find a function that the compiler failed to optimize and that takes too much time, then you can rewrite it to handle the memory yourself. You will then use things like unboxed vectors, IO and ST monad, or even language extensions to access the native machine-level types.
First of all, Haskell does not allow "copying" data to itself, which in the normal sense, means the data is mutable. In Haskell you don't have mutable "variable"s, so you will not be able to modify the value a given variable presents.
All you have did, is define a new variable which have the same name of its previous version. But, to do this properly, you have to refer to the old variable, not the newly defined one. So your original definition
let rec = rec { field=1 }
is a recursive definition, the name rec refer to itself. But what you intended to do, is to refer to the rec defined early on.
So this is a name conflict.
Haskell have some machenism to work around this. One is your "temporary renaming".
For the original example this looks like
let rec' = rec
let rec = rec' { field=1 }
This looks like your given solution. But remember this is only available in a command line environment. If you try to use this in a function, you may have to write
let rec' = rec in let rec = rec' { field=1 } in ...
Here is another workaround, which might be useful when rec is belong to another module (say "MyModule"):
let rec = MyModule.rec { field=1 }

Relational override on 'objects'?

I have a signature
sig Test {
a: Int,
b: Int,
c: Int
}
If I have two instances (atoms?) of this ( x,y:Test )
can I define a relation between these where only some parameters has changed without having to list all the other parameters as equal?
I want to avoid having to list all unchanged fields
as this can be error-prone assuming I have many fields.
Currently I am using x.(a+b+c) = y.(a+next[b]+c) but would like to use something like x = y ++ (b->next[y.b])
from what I understand about Alloy I think the answer is No: you cannot talk about all relations where some atom is involved in without explicitly naming these relations. But some experts may correct me if I'm wrong.

Any nice record Handling tricks in Haskell?

I'm aware of partial updates for records like :
data A a b = A { a :: a, b :: b }
x = A { a=1,b=2 :: Int }
y = x { b = toRational (a x) + 4.5 }
Are there any tricks for doing only partial initialization, creating a subrecord type, or doing (de)serialization on subrecord?
In particular, I found that the first of these lines works but the second does not :
read "A {a=1,b=()}" :: A Int ()
read "A {a=1}" :: A Int ()
You could always massage such input using a regular expression, but I'm curious what Haskell-like options exist.
Partial initialisation works fine: A {a=1} is a valid expression of type A Int (); the Read instance just doesn't bother parsing anything the Show instance doesn't output. The b field is initialised to error "...", where the string contains file/line information to help with debugging.
You generally shouldn't be using Read for any real-world parsing situations; it's there for toy programs that have really simple serialisation needs and debugging.
I'm not sure what you mean by "subrecord", but if you want serialisation/deserialisation that can cope with "upgrades" to the record format to contain more information while still being able to process old (now "partial") serialisations, then the safecopy library does just that.
You cannot leave some value in Haskell "uninitialized" (it would not be possible to "initialize" it later anyway, since Haskell is pure). If you want to provide "default" values for the fields, then you can make some "default" value for your record type, and then do a partial update on that default value, setting only the fields you care about. I don't know how you would implement read for this in a simple way, however.

Resources