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
Line 
1/*
2Author: Yihao Yan
3
4See challenge 3 of: http://etaps2015.verifythis.org/challenges
5
6-----------------
7Problem description:
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
24-----------------
25Verification task:
26
27Implement the data structure with these operations, and specify and
28verify that they behave in the way described above.
29
30-----------------
31Result:
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.
38
39Therefore, the delete and insert functions behave correctly
40
41-----------------
42command:civl verify dancingLinks.c
43
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 {
60 struct Node *left;
61 struct Node *right;
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);
168 // the index of the node which will be deleted
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.