source: CIVL/examples/verifyThis/dancingLinks.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 4.3 KB
RevLine 
[59d519c]1/*
[76f18de]2Author: Yihao Yan
[ab9857b]3
[41eb9b6]4See challenge 3 of: http://etaps2015.verifythis.org/challenges
5
6-----------------
7Problem description:
[ab9857b]8
9Dancing links is a technique introduced in 1979 by Hitotumatu and
10Noshita and later popularized by Knuth. The technique can be used to
11efficiently implement a search for all solutions of the exact cover
12problem, which in its turn can be used to solve Tiling, Sudoku,
13N-Queens, and other problems.
14
15Suppose x points to a node of a doubly linked list; let L[x] and R[x]
16point to the predecessor and successor of that node. Then the operations
17L[R[x]] := L[x];
18R[L[x]] := R[x];
19remove x from the list. The subsequent operations
20L[R[x]] := x;
21R[L[x]] := x;
22will put x back into the list again.
23
[41eb9b6]24-----------------
25Verification task:
26
27Implement the data structure with these operations, and specify and
28verify that they behave in the way described above.
29
[0cdc417]30-----------------
31Result:
[76f18de]32After deleting Node n, all the node remains the same except the left of n
33(if there is any) or the right of n (if there is any). Also, the right of the left of
34n points at the right of n; the left of the right of n points at the left of n.
35
36Then after insertion, the list is restored, which means every node in the list is
37the same with the orignial.
[f7e5282]38
[0cdc417]39Therefore, the delete and insert functions behave correctly
40
41-----------------
42command:civl verify dancingLinks.c
43
[ab9857b]44*/
45
46#include <stdlib.h>
47#include <stdbool.h>
48#include <assert.h>
49#include <time.h>
50
51#ifdef _CIVL
52#include <civlc.cvh>
53$input int N=10;
54$assume (N >= 3);
55#else
56int N=10;
57#endif
58
59struct Node {
[41eb9b6]60 struct Node *left;
61 struct Node *right;
[ab9857b]62};
63
64void insert(struct Node *x) {
65 x->right->left = x;
66 x->left->right = x;
67}
68
69void delete(struct Node *x) {
70 x->right->left = x->left;
71 x->left->right = x->right;
72}
73
74//initilize a linkedlist
75struct Node* init(int n) {
76 struct Node *head = (struct Node *)malloc(sizeof(struct Node));
77 struct Node *temp = head;
78
79 temp->left = NULL;
80 while(n > 1) {
81 struct Node *new = (struct Node *)malloc(sizeof(struct Node));
82
83 temp->right = new;
84 new->left = temp;
85 temp = temp->right;
86 n--;
87 }
88 temp->right = NULL;
89 return head;
90}
91
92struct Node* getNode(struct Node* list, int index) {
93 struct Node *result = list;
94
95 while(index >1) {
96 result = result->right;
97 index--;
98 }
99 return result;
100}
101
102void initNodeArray(struct Node** array, struct Node* list, int n) {
103 struct Node *cur = list;
104 int index=0;
105
106 while(n > 0) {
107 array[index++] = cur;
108 cur = cur->right;
109 n--;
110 }
111}
112
113void verifyDelete(struct Node *list, struct Node **nodeArray, int index, int n) {
114 struct Node *temp1 = list;
115
116 for(int i=0; i<index-1; i++) {
117 assert(temp1 == nodeArray[i]);
118 assert(temp1->left == (nodeArray[i])->left);
119 if(i != index-2) {
120 assert(temp1->right == (nodeArray[i])->right);
121 } else {
122 if(index == n) {
123 assert(temp1->right == NULL);
124 } else {
125 assert(temp1->right == nodeArray[index]);
126 }
127 }
128 temp1 = temp1->right;
129 }
130
131 for(int j=index; j<=n-1; j++) {
132 assert(temp1 == nodeArray[j]);
133 assert(temp1->right == (nodeArray[j])->right);
134 if(j == index) {
135 if(index == 1) {
136 assert(temp1->left == NULL);
137 } else {
138 assert(temp1->left == nodeArray[index-2]);
139 }
140 } else {
141 assert(temp1->left == (nodeArray[j])->left);
142 }
143 temp1 = temp1->right;
144 }
145}
146
147void verifyInsert(struct Node *list, struct Node **nodeArray, int index, int n) {
148 struct Node *temp1 = list;
149
150 for(int k=0;k < n; k++) {
151 assert(temp1 == nodeArray[k]);
152 assert(temp1->left == (nodeArray[k])->left);
153 assert(temp1->right == (nodeArray[k])->right);
154 temp1 = temp1->right;
155 }
156}
157
158int main() {
159 // size of the linked list
160#ifdef _CIVL
161 int n = $choose_int(N-2)+3;
162#else
163 srand(time(NULL));
164 int n = rand()%(N-2)+3;
165#endif
166
167 struct Node *list = init(n);
[41eb9b6]168 // the index of the node which will be deleted
[ab9857b]169#ifdef _CIVL
170 int index = $choose_int(n-2)+2;
171#else
172 int index = rand()%(N-2)+2;
173#endif
174
175 struct Node *x = getNode(list, index);
176 struct Node *nodeArray[n];
177
178 initNodeArray(nodeArray, list, n);
179 delete(x);
180 verifyDelete(list, nodeArray, index, n);
181 insert(x);
182 verifyInsert(list, nodeArray, index, n);
183
184 int t = n;
185 struct Node *temp1 = list;
186
187 while(t >0) {
188 struct Node *temp2 = temp1;
189
190 temp1 = temp1->right;
191 free(temp2);
192 t--;
193 }
194 return 0;
195}
Note: See TracBrowser for help on using the repository browser.