# Lecture 010

struct ssa_header {
string[] data;
int length;
}

int ssa_len(ssa_t A)
//@requires A != NULL;
//@requires A->length = \length(A->data); // added to prove length is actually correct
//@ensures \result >= 0;
//@ensures \result == \length(A->data); // added to ensure what we return is correct

ssa_t ssa_new(int size)
//@requires size >= 0;
//@ensures is_ssa(\result);
//@ensures ssa_len(\result) == size; // although you have is_ssa, you still need to check whether input get considered
{
ssa* A = alloc(ssa);
A->data = alloc_array(string, size);
A->length = size;
return A;
}

string ssa_get(ssa_t A, int i)
//@requires A != NULL;
//@requires A->length = \length(A->data); // for precondition for ssa_len
//@requires 0 <= i && i < ssa_len(A);

void ssa_set(ssa_t A, int i, string x)
//@requires is_ssa(A); // for function that takes SSA as parameter
//@requires 0 <= i && i < ssa_len(A);
//@ensures is_ssa(A); // for function that modifies or return SSA

typedef ssa* ssa_t;



## Representation Invariants

appear multiple time, important property

//@requires A != NULL;
//@requires is_sorted(A->data);
//@requires A->length = \length(A->data);

• precondition for every library function that takes SSA as a parameter

• post-condition for every library function that return or modifies an SSA

### Representation Invariant Function

bool is_ssa(ssa* A) {
if (A==NULL) return false;
//@assert A->length == \length(A->data); // we want to check if A is NULL before doing assert, we don't want it to fail
return is_sorted(A);
}

• to check is_sorted, and all those essential preconditions

• is_ssa is not a part of interface, just make sure we code correctly

Preconditions: ensure safe access of operations below Postconditions:

• ensure we care about the input

• make sure \result correct

• make sure we don't modify unwanted

## Worklist

a family of datastructure

• putting in

• getting out

Different worklist

• Stack: last in first out

• Queues: first in first out

• Priority: receive most interesting ones

Data Type

• string

• wl_t

Functions we need

• wl_retrieve

• wl_new

• wl_empty

### Stack

notice //@ensures(string_equal(pop(S), x)); is not allowed in c0 since it is not pure (purity check) - changes the value. We should use peak

string peak(stack_t S)
//@requires S != NULL;
//@requires !stack_empty(S);
{
string x = pop(S);
push(S, x);
return x;
}


• there are no meaningful loop invariants (its fine because clients don't look into implementation)

### Queues

typedef struct list_node list;
struct listnode {
int data;
list* next; // recursive data structure
// to end a list, put NULL or a pointer to itself or to put a dummy node.
// to implement dummy node, we track both address of start and dummy node. We never look at the dummy node. We can look at a infinitely long segment of list_node
}

bool queue_empty(queue_t S) // O(1)
//@requires S != NULL;

queue_t queue_new()
//@ensures \result!=NULL;
//@ensures queue_empty(\result);

void enq(queue_t S, int x)
//@requires S != NULL;
//@ensures !queue_empty(S);

int deq(queue_t S)
//@requires S != NULL;
//@requires !queue_empty(S);

bool is_segement(list* start, list* end)
//@requires is_acyclic(start); // IMPORTANT
{
list* l = start;
while(l != NULL) {
if (l == end) return true;
l = l->next;
}
return false;
}

// implementing acyclic()
// pointers are 64 bits long (longer than int)
// therefore we can't say that a chain longer than 32 is not a valid chain.

bool is_queue(queue* Q) {
return Q != NULL
&& is_acyclic(Q->front)
&& is_segment(Q->front, Q->back);
}

bool queue_empty(queue* Q)
//@require is_queue(Q);
{
return Q->front == Q->back;
}

queue_t queue_new()
//@require is_queue(Q);
{
queue* Q = alloc(queue);
Q->front = alloc(list);
Q->back = Q->front;
}



Deleting Element

Inserting Element

### Queue as List Node

// list is a node

(see code above)

### Stack

bool stack_empty(stack* S)
//@requires is_stack(S);
{
return S->top == NULL;
}

stack* stack_new()
//@ensures is_stack(\result);
//@ensures stack_empty(\result);
{
stack* S = alloc(stack);
S->top = NULL;
}



• The client's perspective

/* CLAC PROGRAM

: noop ; : dup 1 pick ;

// test if the left most is 0, // if so, do nothing, if not , do fib1 : fib dup if fib1 1 skip noop ;

// test if the left most is 1, // if so, do nothing, if not, do fib_body : fib1 dup 1 - if fib_body 1 skip noop ;

// left minus one and then calculate fib for result -> fib(n-1) // burry what we calculated in, take the original out // minus 2 and then calculate fib for result -> fib(n-2) // add then together fib(n) = fib(n-1)+fib(n-2) : fib_body dup 1 - fib swap 2 - fib + ; */

Table of Content