https://alloy.readthedocs.io/en/latest/language/signatures.html#relations

>[!note]
>Node.prox' = Node.prox
!=
all n:Node | n.prox' = n.prox
= 
prox' = prox

>[!note]
>some b: Bucket | ...


```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 insert[n : Node] {
	always n in ( Bucket.head + Bucket.head.prox)
	always n in Bucket.head or n in Node.prox
	
	//if hash empty -> node to head of bucket
	n.key.hash not in Hash implies
	(
      lone b:Bucket | b.head = none implies b.head' = n
	)
	//if hash empty -> bucket of desired hash, add to next
	n.key.hash in Hash implies
	(
      lone b: Bucket | b.head.key.hash = n.key.hash | b.head.*prox = n
	)
}


pred insert[n : Node] {
  	//nodes always in the head or linked to prox
  	//always n in ( Bucket.head + Bucket.head.prox)
  	always n.key.hash not in Hash {
	  	always lone b: Bucket| b.head = none {
      		b.head = n
      	}
  	}
  

}


```

//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
