CS195Y Lecture 3

2/1/16

Announcement: Oracle is due Thursday (2/4/16), Python Lab tonight 8-10 in Sunlab

Sort Oracle

Insertion sort: pass through the list, putting each record where it belongs.
Properties a sort function should satisfy:

To check for same elements:

What if list1 = ['Alice', 'Bob', 'Bob'] and list2 = ['Alice', 'Alice', 'Bob']?
Currently, our same_elements verifier would fail. This bug can be fixed by counting the number of occurrences of each element in each list, and making sure that the counts match.

To check for ordering:

To generate lists:

Note: Even with a testing oracle, you can never be completely certain that your function works. It is always possible that the implementation works for the exact inputs you test, or inputs up to a certain size, but does not work more generally.

Wouldn't it be nice to be able to exhaustively test all of the possible inputs, up to a certain size?

Introduction to Alloy

The idea of Alloy is not to analyze code, as written, but rather to analyze the design of a system, before you even write the code.
Tic Tac Toe
Rules:

How would you model Tic Tac Toe? How do you represent the game to the computer, without just implementing the game itself?

Instead of enumerating the possible states, can we somehow describe the rules themselves?
We need some way of talking about the structure of the board.

abstract sig Player {} -- There is a type called Player, abstract means we are going to give
subtypes of Player, and every "Player" is one of these subtypes
one sig X extends Player {} -- X is a type of Player, one means there can only be one
instance of X. That is, all Xs are the same.
run {} -- Tells Alloy, "given the constraints I just gave you, find me an example"

sig Board {
  places : (Index -> Index) -> lone Player
}

This says, every Board has a mapping from (row, column) locations on the board to pieces that are played.
lone keyword means that at every pair of indices, there is either 0 or 1 Player at that place.
What if we said one sig Board? Then, there could only be one possible arrangement of pieces on the board.
Alloy is showing you samples from all of the possible boards, not necessarily boards that should be part of the same game.
If we want to make sure that players can't play in filled boxes, we need to write that constraint into our model.
run {#places > 1} -- Give me an instance with at least two pieces on the board. Here, we're asking "is this even possible?", and Alloy responds by showing us an example, or telling us it can't find one.
How do we describe to Alloy what it means for it to be O's turn?
It is O's turn if there is one more X than O on the board.
We want a predicate pred XTurn[b: Board] which will be true if it is X's turn for the given board, false otherwise.
{r, c : Index | b.places[r][c] = X} -- this is a set comprehension that includes all the pairs of indices such that the given board has an X at the pair of indices.