/* * Stacks of string * * 15-122 Principles of Imperative Computation */ /*** Interface ***/ // typedef _______ stack; typedef struct stack_header* stack; bool stack_empty(stack S); /* O(1) */ stack stack_new(); /* O(1) */ void push(stack S, string x); /* O(1) */ string pop(stack S) /* O(1) */ /*@requires !stack_empty(S); @*/ ; /*** Implementation ***/ /* Aux structure of linked lists of strings */ struct slist_node { string data; struct slist_node* next; }; typedef struct slist_node slist; /* is_segment_slist(start, end) will diverge if list is circular! */ bool is_segment_slist(slist* start, slist* end) { slist* p = start; while (p != end) { if (p == NULL) return false; p = p->next; } return true; } /* Stacks of integers */ struct stack_header { slist* top; slist* bottom; }; bool is_stack(stack S) { if (S == NULL) return false; if (S->top == NULL || S->bottom == NULL) return false; if (!is_segment_slist(S->top, S->bottom)) return false; return true; } 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(struct stack_header); slist* l = alloc(struct slist_node); /* does not need to be initialized! */ 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(struct slist_node); 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; } stack stack_copy(stack S) //@requires is_stack(S); //@ensures is_stack(\result); { stack S2 = alloc(struct stack_header); S2->top = S->top; S2->bottom = S->bottom; return S2; }