2023-11-06 12:25:52 +00:00
|
|
|
https://alloy.readthedocs.io/en/latest/language/signatures.html#relations
|
2023-11-06 12:15:52 +00:00
|
|
|
|
|
|
|
>[!note]
|
|
|
|
>Node.prox' = Node.prox
|
|
|
|
!=
|
|
|
|
all n:Node | n.prox' = n.prox
|
|
|
|
=
|
|
|
|
prox' = prox
|
|
|
|
|
2023-11-06 12:45:52 +00:00
|
|
|
>[!note]
|
|
|
|
>some b: Bucket | ...
|
|
|
|
|
|
|
|
|
2023-11-06 12:25:52 +00:00
|
|
|
```c
|
|
|
|
// Recall the hash table Alloy model,
|
|
|
|
// now with mutable lists inside the buckets.
|
|
|
|
|
|
|
|
sig Bucket {
|
|
|
|
var head : lone Node
|
|
|
|
}
|
|
|
|
sig Node {
|
|
|
|
key : one Key,
|
|
|
|
var prox : lone Node
|
|
|
|
}
|
|
|
|
sig Key {
|
|
|
|
hash : one Hash
|
|
|
|
}
|
|
|
|
sig Hash {}
|
|
|
|
|
|
|
|
// Specify the operation of inserting a node
|
|
|
|
// in the hash table. The node should be
|
|
|
|
// inserted at the head of a bucket.
|
|
|
|
// If the operation only works well when the
|
|
|
|
// hash of the new node does not exist in the
|
|
|
|
// table you get Two points. If it always
|
|
|
|
// works well you get Five points. Use the
|
|
|
|
// respective commands to check how many
|
|
|
|
// points you have.
|
|
|
|
|
2023-11-06 23:08:39 +00:00
|
|
|
|
2023-11-06 12:25:52 +00:00
|
|
|
pred insert[n : Node] {
|
2023-11-10 11:55:55 +00:00
|
|
|
always n in ( Bucket.head + Bucket.head.prox)
|
|
|
|
always n in Bucket.head or n in Node.prox
|
2023-11-10 12:11:37 +00:00
|
|
|
|
|
|
|
//if hash empty -> node to head of bucket
|
2023-11-06 23:08:39 +00:00
|
|
|
n.key.hash not in Hash implies
|
|
|
|
(
|
2023-11-10 11:45:55 +00:00
|
|
|
lone b:Bucket | b.head = none implies b.head' = n
|
2023-11-10 12:11:37 +00:00
|
|
|
)
|
|
|
|
//if hash empty -> bucket of desired hash, add to next
|
|
|
|
n.key.hash in Hash implies
|
|
|
|
(
|
2023-11-10 11:45:55 +00:00
|
|
|
lone b: Bucket | b.head.key.hash = n.key.hash | b.head.*prox = n
|
2023-11-10 12:11:37 +00:00
|
|
|
)
|
2023-11-06 12:25:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-10 12:11:37 +00:00
|
|
|
pred insert[n : Node] {
|
|
|
|
//nodes always in the head or linked to prox
|
|
|
|
//always n in ( Bucket.head + Bucket.head.prox)
|
2023-11-10 12:32:06 +00:00
|
|
|
always n.key.hash not in Hash {
|
2023-11-10 15:28:53 +00:00
|
|
|
always lone b: Bucket| b.head = none {
|
|
|
|
b.head = n
|
|
|
|
}
|
2023-11-10 12:11:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-11-06 23:08:39 +00:00
|
|
|
|
2023-11-06 12:25:52 +00:00
|
|
|
```
|
2023-11-10 17:46:05 +00:00
|
|
|
|
|
|
|
//Solved
|
|
|
|
```c
|
|
|
|
// Recall the hash table Alloy model,
|
|
|
|
// now with mutable lists inside the buckets.
|
|
|
|
|
|
|
|
sig Bucket {
|
|
|
|
var head : lone Node
|
|
|
|
}
|
|
|
|
sig Node {
|
|
|
|
key : one Key,
|
|
|
|
var prox : lone Node
|
|
|
|
}
|
|
|
|
sig Key {
|
|
|
|
hash : one Hash
|
|
|
|
}
|
|
|
|
sig Hash {}
|
|
|
|
|
|
|
|
// Specify the operation of inserting a node
|
|
|
|
// in the hash table. The node should be
|
|
|
|
// inserted at the head of a bucket.
|
|
|
|
// If the operation only works well when the
|
|
|
|
// hash of the new node does not exist in the
|
|
|
|
// table you get Two points. If it always
|
|
|
|
// works well you get Five points. Use the
|
|
|
|
// respective commands to check how many
|
|
|
|
// points you have.
|
|
|
|
|
|
|
|
pred nodeToHead[n : Node]{
|
|
|
|
//node not in hash
|
|
|
|
n.key.hash not in Bucket.head.key.hash
|
|
|
|
|
|
|
|
some b : Bucket | {
|
|
|
|
b.head= none and b.head' = n //put node in the head
|
|
|
|
all x : Bucket - b | x.head' = x.head //everything remains the same
|
|
|
|
all y : Node | y.prox' = y.prox //all nodes remain the same
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pred nodeToTail[n: Node]{
|
|
|
|
//node not in linked lists of buckets
|
|
|
|
n not in Bucket.head.*prox
|
|
|
|
|
|
|
|
//node in hash
|
|
|
|
n.key.hash in Bucket.head.key.hash
|
|
|
|
|
|
|
|
some b : Bucket | {
|
|
|
|
b.head.key.hash = n.key.hash and { //same hash
|
|
|
|
(b.head' = n and n.prox' = b.head) //new head
|
|
|
|
all x : Bucket - b | x.head' = x.head //all other buckets remain the same
|
|
|
|
all y : Node - n | y.prox' = y.prox //all other nodes remain the same
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pred insert[n : Node] {
|
|
|
|
nodeToHead[n] or nodeToTail [n]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
http://alloy4fun.inesctec.pt/mnvLbxeXWRuhsnQSd
|