/* * Stacks * * 15-122 Principles of Imperative Computation */ /*** Interface ***/ // typedef ______* stack_t; typedef struct stack_header* stack_t; bool stack_empty(stack_t S) /* O(1) */ /*@requires S != NULL; @*/; stack_t stack_new() /* O(1) */ /*@ensures \result != NULL; @*/ /*@ensures stack_empty(\result); @*/; void push(stack_t S, string x) /* O(1) */ /*@requires S != NULL; @*/; string pop(stack_t S) /* O(1) */ /*@requires S != NULL; @*/ /*@requires !stack_empty(S); @*/; /*** Implementation ***/ /* Aux structure of linked lists of strings */ typedef struct slist_node slist; struct slist_node { string data; slist* next; }; /* is_segment_slist(start, end) will diverge if list is circular! */ bool is_segment_slist(slist* start, slist* end) { if (start == NULL) return false; if (start == end) return true; return is_segment_slist(start->next, end); } /* Stacks */ typedef struct stack_header stack; struct stack_header { slist* top; slist* bottom; }; bool is_stack(stack* S) { return S != NULL && S->top != NULL && S->bottom != NULL && is_segment_slist(S->top, S->bottom); } bool stack_empty(stack* S) //@requires is_stack(S); { return S->top == S->bottom; } stack* stack_new() //@ensures is_stack(\result); //@ensures stack_empty(\result); { stack* S = alloc(stack); slist* l = alloc(slist); S->top = l; S->bottom = l; return S; } void push(stack* S, string x) //@requires is_stack(S); //@ensures is_stack(S); { slist* l = alloc(slist); l->data = x; l->next = S->top; S->top = l; } string pop(stack* S) //@requires is_stack(S); //@requires !stack_empty(S); //@ensures is_stack(S); { string e = S->top->data; S->top = S->top->next; return e; }