view src/insert_verification/main.c @ 14:1bbaafdafa47

Enumerates all paths
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Sun, 20 Mar 2016 19:05:43 +0900
parents f0a1f02e8493
children d6d6e075b498
line wrap: on
line source

#include <stdio.h>

#include "akashaLLRBContext.h"
#include "akashaCS.h"

extern void allocator(struct Context* context);

void printTree(struct Node* node, int n) {
    if (node != 0) {
        printTree(node->left, n+1);
        for (int i=0;i<n;i++)
            printf("  ");
        printf("key=%d value=%d color=%s\t%p\n", node->key, node->value,/* n, */node->color==0? "R":"B", node);
        printTree(node->right, n+1);
    }
}

__code showTree_stub(struct Context* context) {
    goto showTree(context, &context->data[Tree]->tree);
}

__code showTree(struct Context* context, struct Tree* tree) {
    printTree(tree->root, 0);
    puts("");

    goto meta(context, Exit);
}

__code verifySpecification(struct Context* context) {
}

__code iterateInsertion_stub(struct Context* context) {
    goto iterateInsertion(context, &context->data[Iter]->iterator, &context->data[Node]->node);
}

__code iterateInsertion(struct Context* context, struct Iterator* iter, struct Node* node) {
    // puts all elements in iterator into tree.
    node->key   = iter->head->val;
    node->value = iter->head->val;
    iter->head  = iter->head->next;

    if (iter->head == iter->last) {
        context->next = ShowTree;
    } else {
        context->next = IterateInsertion;
    }
    goto meta(context, Put);
}

__code putAndGoToNextDepth_stub(struct Context* context) {
    goto putAndGoToNextDepth(context, &context->data[Iter]->iterator, &context->data[Tree]->tree, &context->data[Node]->node);
}

__code putAndGoToNextDepth(struct Context* context, struct Iterator* iter, struct Tree* tree, struct Node* node) {
    node->key   = iter->head->val;
    node->value = iter->head->val;
    iter->head  = iter->head->next;

    printf("%d\n", node->value);

    if (iter->head == iter->last) {
        context->next = GoToPreviousDepth;
    } else {
        context->next = DuplicateIterator;
    }
    goto meta(context, Put);
}

__code duplicateIterator_stub(struct Context* context) {
    goto duplicateIterator(context, &context->data[Allocate]->allocate, &context->data[Iter]->iterator);
}

__code duplicateIterator(struct Context* context, struct Allocate* allocate, struct Iterator* iter) {
    struct Iterator* newIter = context->heap;
    allocate->size = sizeof(struct Iterator);
    allocator(context);

    struct IterElem* dup = context->heap;
    allocate->size = sizeof(struct IterElem);
    allocator(context);

    dup->val  = iter->head->val;
    dup->next = NULL;

    newIter->previousDepth = iter;
    newIter->head          = dup;
    newIter->last          = NULL;
    context->data[Iter]    = (union Data*) newIter;

    goto duplicateIteratorElem_stub(context);
}

__code duplicateIteratorElem_stub(struct Context* context) {
    goto duplicateIteratorElem(context, &context->data[Allocate]->allocate, &context->data[Iter]->iterator);
}

__code duplicateIteratorElem(struct Context* context, struct Allocate* allocate, struct Iterator* iter) {
    // All elements in iterator must be unique.

    if ((iter->last != NULL) && (iter->last == iter->previousDepth->last)) {
        goto meta(context, ShowTree); /* copy tree */
    }
    struct IterElem* dup = context->heap;
    allocate->size = sizeof(struct IterElem);
    allocator(context);

    struct IterElem *oldElem = iter->previousDepth->head;
    struct IterElem *newElem = iter->head;


    while ((newElem->next != NULL) && (oldElem->val == newElem->val)) {
        // FIXME: simple implementation O(n^2)
        oldElem = oldElem->next;
        newElem = newElem->next;
    }

    dup->val         = oldElem->next->val;
    newElem->next    = dup;

    if (oldElem->next == iter->previousDepth->last) {
        dup->next  = iter->head;
        iter->last = dup;
        goto duplicateTree_stub(context); // meta
    }

    goto duplicateIteratorElem_stub(context); // meta
}

__code duplicateTree_stub(struct Context* context) {
    goto duplicateTree(context, &context->data[Tree]->tree, &context->data[Iter]->iterator);
}

__code duplicateTree(struct Context* context, struct Tree* tree, struct Iterator* iter) {
    // Tree must be non destructive.
    // If you use destructive tree, you must copy tree.
    iter->previousDepth->tree = tree;
    goto meta(context, PutAndGoToNextDepth);
}

__code goToPreviousDepth(struct Context* context) {
    struct Iterator* finishedIter = &context->data[Iter]->iterator;

    if (finishedIter->previousDepth == NULL) {
        goto meta(context, ShowTree); // all enumerations finished.
    }

    context->data[Iter] = (union Data*)finishedIter->previousDepth;
    context->data[Tree] = (union Data*)finishedIter->previousDepth->tree;
    // TODO: cleanup memory

    goto meta(context, PutAndGoToNextDepth);
}

int main(int argc, char const* argv[]) {
    goto startCode(PutAndGoToNextDepth);
}