Skip to content

Commit 3d8662d

Browse files
committed
some tidying up of the mergesort example
1 parent 7a81691 commit 3d8662d

File tree

1 file changed

+83
-95
lines changed

1 file changed

+83
-95
lines changed

tests/cn/mergesort.c

Lines changed: 83 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,160 @@
1-
struct int_list {
2-
int head;
3-
struct int_list* tail;
1+
struct node {
2+
int value;
3+
struct node* next;
44
};
55

66
/*@
7-
datatype seq {
8-
Seq_Nil {},
9-
Seq_Cons {i32 head, datatype seq tail}
7+
datatype list {
8+
Nil {},
9+
Cons {i32 head, list tail}
1010
}
1111
12-
predicate (datatype seq) IntList(pointer p) {
12+
predicate (list) List(pointer p) {
1313
if (is_null(p)) {
14-
return Seq_Nil{};
14+
return Nil {};
1515
} else {
16-
take H = Owned<struct int_list>(p);
17-
assert (is_null(H.tail) || !addr_eq(H.tail, NULL));
18-
take tl = IntList(H.tail);
19-
return (Seq_Cons { head: H.head, tail: tl });
16+
take node = Owned<struct node>(p);
17+
take tl = List(node.next);
18+
return (Cons { head: node.value, tail: tl });
2019
}
2120
}
2221
23-
function [rec] ({datatype seq fst, datatype seq snd}) cn_split(datatype seq xs)
24-
{
22+
function [rec] ({list fst, list snd}) cn_split(list xs) {
2523
match xs {
26-
Seq_Nil {} => {
27-
{fst: Seq_Nil{}, snd: Seq_Nil{}}
24+
Nil {} => {
25+
{fst: Nil {}, snd: Nil {}}
2826
}
29-
Seq_Cons {head: h1, tail: Seq_Nil{}} => {
30-
{fst: Seq_Nil{}, snd: xs}
27+
Cons {head: h1, tail: Nil {}} => {
28+
{fst: Nil {}, snd: xs}
3129
}
32-
Seq_Cons {head: h1, tail: Seq_Cons {head : h2, tail : tl2 }} => {
30+
Cons {head: h1, tail: Cons {head : h2, tail : tl2 }} => {
3331
let P = cn_split(tl2);
34-
{fst: Seq_Cons { head: h1, tail: P.fst},
35-
snd: Seq_Cons { head: h2, tail: P.snd}}
32+
{fst: Cons { head: h1, tail: P.fst},
33+
snd: Cons { head: h2, tail: P.snd}}
3634
}
3735
}
3836
}
3937
40-
function [rec] (datatype seq) cn_merge(datatype seq xs, datatype seq ys) {
38+
function [rec] (list) cn_merge(list xs, list ys) {
4139
match xs {
42-
Seq_Nil {} => { ys }
43-
Seq_Cons {head: x, tail: xs1} => {
40+
Nil {} => {
41+
ys
42+
}
43+
Cons {head: x, tail: xs1} => {
4444
match ys {
45-
Seq_Nil {} => { xs }
46-
Seq_Cons{ head: y, tail: ys1} => {
45+
Nil {} => {
46+
xs
47+
}
48+
Cons { head: y, tail: ys1} => {
4749
let tail = cn_merge(xs1, ys1);
4850
(x < y) ?
49-
(Seq_Cons{ head: x, tail: Seq_Cons {head: y, tail: tail}})
50-
: (Seq_Cons{ head: y, tail: Seq_Cons {head: x, tail: tail}})
51+
(Cons { head: x, tail: Cons {head: y, tail: tail}})
52+
: (Cons { head: y, tail: Cons {head: x, tail: tail}})
5153
}
5254
}
5355
}
5456
}
5557
}
5658
57-
function [rec] (datatype seq) cn_mergesort(datatype seq xs) {
59+
function [rec] (list) cn_mergesort(list xs) {
5860
match xs {
59-
Seq_Nil{} => { xs }
60-
Seq_Cons{head: x, tail: Seq_Nil{}} => { xs }
61-
Seq_Cons{head: x, tail: Seq_Cons{head: y, tail: zs}} => {
62-
let P = cn_split(xs);
63-
let L1 = cn_mergesort(P.fst);
64-
let L2 = cn_mergesort(P.snd);
65-
cn_merge(L1, L2)
66-
}
61+
Nil {} => {
62+
xs
63+
}
64+
Cons {head: x, tail: Nil {}} => {
65+
xs
66+
}
67+
Cons {head: x, tail: Cons {head: y, tail: zs}} => {
68+
let P = cn_split(xs);
69+
let L1 = cn_mergesort(P.fst);
70+
let L2 = cn_mergesort(P.snd);
71+
cn_merge(L1, L2)
6772
}
73+
}
6874
}
6975
@*/
7076

71-
struct int_list_pair {
72-
struct int_list* fst;
73-
struct int_list* snd;
77+
struct node_pair {
78+
struct node* fst;
79+
struct node* snd;
7480
};
7581

76-
struct int_list_pair split(struct int_list *xs)
77-
/*@ requires is_null(xs) || !addr_eq(xs, NULL); @*/
78-
/*@ requires take Xs = IntList(xs); @*/
79-
/*@ ensures take Ys = IntList(return.fst); @*/
80-
/*@ ensures take Zs = IntList(return.snd); @*/
81-
/*@ ensures is_null(return.fst) || !addr_eq(return.fst, NULL); @*/
82-
/*@ ensures is_null(return.snd) || !addr_eq(return.snd, NULL); @*/
82+
struct node_pair split(struct node *xs)
83+
/*@ requires take Xs = List(xs); @*/
84+
/*@ ensures take Ys = List(return.fst); @*/
85+
/*@ ensures take Zs = List(return.snd); @*/
8386
/*@ ensures {fst: Ys, snd: Zs} == cn_split(Xs); @*/
8487
{
88+
/*@ unfold cn_split(Xs); @*/
8589
if (xs == 0) {
86-
/*@ unfold cn_split(Xs); @*/
87-
struct int_list_pair r = {.fst = 0, .snd = 0};
90+
struct node_pair r = {.fst = 0, .snd = 0};
8891
return r;
8992
} else {
90-
struct int_list *cdr = xs -> tail;
93+
struct node *cdr = xs->next;
9194
if (cdr == 0) {
92-
/*@ unfold cn_split(Xs); @*/
93-
struct int_list_pair r = {.fst = 0, .snd = xs};
95+
struct node_pair r = {.fst = 0, .snd = xs};
9496
return r;
9597
} else {
96-
/*@ unfold cn_split(Xs); @*/
97-
struct int_list_pair p = split(cdr->tail);
98-
xs->tail = p.fst;
99-
cdr->tail = p.snd;
100-
struct int_list_pair r = {.fst = xs, .snd = cdr};
98+
struct node_pair p = split(cdr->next);
99+
xs->next = p.fst;
100+
cdr->next = p.snd;
101+
struct node_pair r = {.fst = xs, .snd = cdr};
101102
return r;
102103
}
103104
}
104105
}
105106

106-
struct int_list* merge(struct int_list *xs, struct int_list *ys)
107-
/*@ requires is_null(xs) || !addr_eq(xs, NULL); @*/
108-
/*@ requires is_null(ys) || !addr_eq(ys, NULL); @*/
109-
/*@ requires take Xs = IntList(xs); @*/
110-
/*@ requires take Ys = IntList(ys); @*/
111-
/*@ ensures is_null(return) || !addr_eq(return, NULL); @*/
112-
/*@ ensures take Zs = IntList(return); @*/
107+
struct node* merge(struct node *xs, struct node *ys)
108+
/*@ requires take Xs = List(xs); @*/
109+
/*@ requires take Ys = List(ys); @*/
110+
/*@ ensures take Zs = List(return); @*/
113111
/*@ ensures Zs == cn_merge(Xs, Ys); @*/
114112
{
113+
/*@ unfold cn_merge(Xs, Ys); @*/
115114
if (xs == 0) {
116-
/*@ unfold cn_merge(Xs, Ys); @*/
117115
return ys;
118116
} else {
119-
/*@ unfold cn_merge(Xs, Ys); @*/
120117
if (ys == 0) {
121-
/*@ unfold cn_merge(Xs, Ys); @*/
122118
return xs;
123119
} else {
124-
/*@ unfold cn_merge(Xs, Ys); @*/
125-
struct int_list *zs = merge(xs->tail, ys->tail);
126-
if (xs->head < ys->head) {
127-
xs->tail = ys;
128-
ys->tail = zs;
120+
struct node *zs = merge(xs->next, ys->next);
121+
if (xs->value < ys->value) {
122+
xs->next = ys;
123+
ys->next = zs;
129124
return xs;
130125
} else {
131-
ys->tail = xs;
132-
xs->tail = zs;
126+
ys->next = xs;
127+
xs->next = zs;
133128
return ys;
134129
}
135130
}
136131
}
137132
}
138133

139-
struct int_list* naive_mergesort(struct int_list *xs)
140-
/*@ requires is_null(xs) || !addr_eq(xs, NULL); @*/
141-
/*@ requires take Xs = IntList(xs); @*/
142-
/*@ ensures take Ys = IntList(return); @*/
143-
/*@ ensures is_null(return) || !addr_eq(return, NULL); @*/
134+
struct node* naive_mergesort(struct node *xs)
135+
/*@ requires take Xs = List(xs); @*/
136+
/*@ ensures take Ys = List(return); @*/
144137
/*@ ensures Ys == cn_mergesort(Xs); @*/
145138
{
139+
/*@ unfold cn_mergesort(Xs); @*/
146140
if (xs == 0) {
147-
/*@ unfold cn_mergesort(Xs); @*/
141+
return xs;
142+
} else if (xs->next == 0) {
148143
return xs;
149144
} else {
150-
struct int_list *tail = xs->tail;
151-
if (tail == 0) {
152-
/*@ unfold cn_mergesort(Xs); @*/
153-
return xs;
154-
} else {
155-
/*@ unfold cn_mergesort(Xs); @*/
156-
struct int_list_pair p = split(xs);
157-
p.fst = naive_mergesort(p.fst);
158-
p.snd = naive_mergesort(p.snd);
159-
return merge(p.fst, p.snd);
160-
}
145+
struct node_pair p = split(xs);
146+
p.fst = naive_mergesort(p.fst);
147+
p.snd = naive_mergesort(p.snd);
148+
return merge(p.fst, p.snd);
161149
}
162150
}
163151

164152
int main(void)
165153
/*@ trusted; @*/
166154
{
167-
struct int_list i3 = {.head = 3, .tail = 0};
168-
struct int_list i2 = {.head = 4, .tail = &i3};
169-
struct int_list i1 = {.head = 2, .tail = &i2};
155+
struct node i3 = {.value = 3, .next = 0};
156+
struct node i2 = {.value = 4, .next = &i3};
157+
struct node i1 = {.value = 2, .next = &i2};
170158

171-
struct int_list *sorted_i1 = naive_mergesort(&i1);
159+
struct node *sorted_i1 = naive_mergesort(&i1);
172160
}

0 commit comments

Comments
 (0)