CS1950Y Lecture 3: Introduction to Modelling in Alloy
January 29, 2018


First Reading has been posted! (There is a free online version of the textbook)

Learning Alloy through modeling the game Tic Tac Toe

What do we need to model Tic Tac Toe? Players, moves, board...

abstract sig Player
one sig PX extends Player {}
one sig PO extends Player {}
run{}

We use sig to model types in alloy. abstract in alloy means we don't have an implementation of the type (in the above example, Player), but we can have instances of the type (in the above example, PO and P1.

When we click on the Instance, we can view visualizations of our model. To see more instances, we can then click the Next button. Alloy finds instances up to a bound (which is why it will eventually stop showing instances).
For this model, PO and PX model both the players and where the players move.
The Index sig for this model will represent different places on the board:

		abstract sig Index {}
one sig One extends Index {}
one sig Two extends Index {}
one sig Three extends Index {}

Does Alloy understand numbers? Stay tuned...
Next we want to say that each board contains many relations (described by the -> notation):
		one sig Board {
			places: (Index -> Index) -> Player
		}
		
	

Alloy's visualizer is optimized for directed graphs. To take a closer look at a complicated model, Tim clicked on the Tree view.

What does this entry mean: One$0 -> One$0 -> PO$0 ?
Answer: Player 0 played on the upper left corner of the board.

What are all of the $0's?
Answer: If we hadn't specified that there is only one instance of PO, then there might be multiple instances of PO. So the zeros represent that we are looking at the first instance of PO. We could also have PO$1 and so on if we didn't have our one specification. The $number represents the nth instance of the type.

When we run run {#Board > 1}, what happens?
Answer: First off, this translates as: "alloy, give me a world where there is more than one Board" So we ran it, and Alloy returned: No instance found. Predicate may be inconsistent. The reason this returned no instances is because we specified that we will only have one board in the line one sig Board.

What might run {#places > 7} mean?
Answer: We will only see boards that have more than 7 places. But, alloy still returns No instance found.

Why does alloy still return no instances?
Answer: Alloy doesn't have the ability to count high enough. The default number of integers in Alloy is 3.

But how then did Alloy return instances with more than 9 places before?
Answer: Alloy doesn't like to count! By telling Alloy we want to see run {#places > 7}, we are asking Alloy to count how many places it needs. Before when it returned 9 places, it didn't need to count.

When we ran run {#places > 7} for 9 int in an attempt to increase the number of integers, we got: A type error has occurred: Alloy couldn't fit the number of things that might be true in java's maximum integer.
Why not?
Answer: 9 int doesn't mean 9 integers, it means 9 bit. So let's try running for 5 int instead!

What does it mean for it to be PO's turn versus player X's turn?
Answer: If there are the same number of O's and X's across the board, it is player X's turn. If there are more X's than O's, it is player O's turn.

pred xturn [b: Board] {}
pred here is creating a boolean function to say whether it is PX's turn. To do this, we want to count the number of places that player X has played:

		#{r,c : Index | b.places[r][c] = PX}
	
And then we also want to count the number of places that O has played:

		#{r,c : Index | b.places[r][c] = PO}
	
To check that it is player X's turn, we want to see if the number of places are equal:
		
		pred xturn [b: Board] {
			#{r,c : Index | b.places[r][c] = PX} =
			#{r,c : Index | b.places[r][c] = PO}
		}
		
	
To then see an instance where it is player X's turn, we can run run xturn. But wait! We have an instance where player X and player O have played in the same spot... We never specified that each spot can only have one player!

This counter example that alloy provided showed us an initial hole in our reasoning. This is one of the powers of alloy, because it can show us instances which we have overlooked an important piece of our software model.

To fix this, Tim wrote a fact called atMostOneMarkPerSquare.