Lecture 010

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

typedef struct ssa_header ssa;

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);

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);
}

Preconditions: ensure safe access of operations below Postconditions:

Interface and Implementation contracts can be different

Interface and Implementation contracts can be different

Structure of C0 Library File

Structure of C0 Library File

Worklist

a family of datastructure

Different worklist

Data Type

Functions we need

Stack

Stack Interface

Stack Interface

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;
}

Bad Implementation

Bad Implementation

Fine Implementation

Fine Implementation

Queues

Queues Interface

Queues Interface

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;
}


Other Ways to Implement is_segment()

Other Ways to Implement is_segment()

Deleting Element

From Start

From Start

From End

From End

Inserting Element

From Start

From Start

Bad Insert

Bad Insert

Good Insert

Good Insert

Complexity

Complexity

Queue as List Node

Queue

Queue

Queue the struct

Queue the struct
// list is a node

(see code above)

Stack

Stack

Stack

Stack the struct

Stack the struct

We can set last pointer NULL because we don't need to modify last

We can set last pointer NULL because we don't need to modify last

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;
}

CANNOT GET RID OF

CANNOT GET RID OF

BUT

BUT

Pop will not work

Pop will not work

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