Skip to content

Commit e0fc29a

Browse files
committed
Fixed bug in DFA minimization
1 parent 0433915 commit e0fc29a

File tree

3 files changed

+54
-19
lines changed

3 files changed

+54
-19
lines changed

code/rwlock_btest2.hny

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import rwlock
22

33
const N_READERS = 2
4-
const N_WRITERS = 0
4+
const N_WRITERS = 1
55

66
rw = rwlock.RWlock()
77

harmony_model_checker/charm/charm.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,7 +4086,9 @@ static bool distin_helper(void *env, const void *key, unsigned int key_size, voi
40864086
struct dict_assoc *da1 = distin_env->de->todo[dst1];
40874087
struct dfa_node *dn1 = (struct dfa_node *) &da1[1];
40884088

4089-
// printf("CMP %p(%p) %p(%p)\n", dn1, dn1->rep, dn2, dn2->rep);
4089+
// if (dn1->rep != dn2->rep) {
4090+
// printf("CMP %s %u(%u) %u(%u)\n", value_string(* (hvalue_t *) key), dn1->id, dn1->rep->id, dn2->id, dn2->rep->id);
4091+
// }
40904092

40914093
return dn1->rep == dn2->rep;
40924094
}
@@ -4249,10 +4251,17 @@ static unsigned int nfa2dfa(FILE *hfa, struct dict *symbols){
42494251

42504252
// Now keep partitioning until no new partitions are formed
42514253
bool new_partition = true;
4252-
unsigned int work_ctr = 0;
4254+
unsigned int work_ctr = 0; // for pacifier
42534255
for (unsigned int round = 0; new_partition; round++) {
4256+
// Mark all nodes in each partition with a unique id.
4257+
for (unsigned int i = 0; i < n_new; i++) {
4258+
for (struct dfa_node *dn = new[i]; dn != NULL; dn = dn->next) {
4259+
dn->rep = new[i];
4260+
}
4261+
}
4262+
42544263
#ifdef notdef
4255-
printf("DFA_MINIFY PARTITION %u\n", n_new);
4264+
printf("DFA_MINIFY PARTITION round=%u, #partitions=%u\n", round, n_new);
42564265
printf("Partitions:\n");
42574266
for (unsigned int i = 0; i < n_new; i++) {
42584267
printf(" %u:", i);
@@ -4274,7 +4283,7 @@ static unsigned int nfa2dfa(FILE *hfa, struct dict *symbols){
42744283
// Go through each of the old partitions
42754284
new_partition = false;
42764285
for (unsigned i = 0; i < n_old; i++) {
4277-
// printf("Partition %u\n", i);
4286+
// printf("Partition %u #new=%u\n", i, n_new);
42784287

42794288
// Repartition the group based on distinguishability
42804289

@@ -4290,18 +4299,20 @@ static unsigned int nfa2dfa(FILE *hfa, struct dict *symbols){
42904299
continue;
42914300
}
42924301

4293-
// Initialize the first partition.
4302+
// Initialize the first partition by moving over one node.
42944303
unsigned int k = n_new;
42954304
old[i] = dn->next;
42964305
new[n_new++] = dn;
4297-
dn->rep = dn;
42984306
dn->next = NULL;
42994307

4308+
// Now look at all the other nodes in the partition
43004309
while ((dn = old[i]) != NULL) {
43014310
old[i] = dn->next;
43024311

4312+
43034313
// See if the node fits into one of the existing partitions
43044314
unsigned int j = k;
4315+
// printf("check j=%u dn=%u rep=%u\n", j, dn->id, dn->rep->id);
43054316
for (; j < n_new; j++) {
43064317

43074318
// Pacifier
@@ -4311,8 +4322,7 @@ static unsigned int nfa2dfa(FILE *hfa, struct dict *symbols){
43114322
}
43124323

43134324
if (indistinguishable(&de, dn, new[j])) {
4314-
// printf("ind %u %u %u\n", j, dn->id, new[j]->id);
4315-
dn->rep = new[j]->rep;
4325+
// printf("ind j=%u dn=%u rep=%u\n", j, dn->id, new[j]->id);
43164326
dn->next = new[j];
43174327
new[j] = dn;
43184328
break;
@@ -4321,7 +4331,6 @@ static unsigned int nfa2dfa(FILE *hfa, struct dict *symbols){
43214331

43224332
// Otherwise, create a new partition
43234333
if (j == n_new) {
4324-
dn->rep = dn;
43254334
dn->next = NULL;
43264335
new[n_new++] = dn;
43274336
new_partition = true;
@@ -5591,9 +5600,9 @@ int exec_model_checker(int argc, char **argv){
55915600
fprintf(hfa, "}\n");
55925601
fclose(hfa);
55935602

5594-
struct dfa *dfa = dfa_read(&workers[0].allocator, hfaout);
5595-
struct gnfa *gnfa = gnfa_from_dfa(dfa);
5596-
gnfa_rip(gnfa);
5603+
// struct dfa *dfa = dfa_read(&workers[0].allocator, hfaout);
5604+
// struct gnfa *gnfa = gnfa_from_dfa(dfa);
5605+
// gnfa_rip(gnfa);
55975606
}
55985607
}
55995608

harmony_model_checker/charm/gnfa.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,13 @@ void regexp_dump(struct regexp *re, unsigned int indent){
6565
}
6666

6767
struct regexp *regexp_epsilon(){
68-
struct regexp *re = malloc(sizeof(*re));
69-
re->type = RE_EPSILON;
70-
return re;
68+
static struct regexp *eps;
69+
70+
if (eps == NULL) {
71+
eps = malloc(sizeof(*eps));
72+
eps->type = RE_EPSILON;
73+
}
74+
return eps;
7175
}
7276

7377
struct regexp *regexp_symbol(hvalue_t symbol){
@@ -78,12 +82,34 @@ struct regexp *regexp_symbol(hvalue_t symbol){
7882
}
7983

8084
struct regexp *regexp_disjunction(struct regexp *disj[], unsigned int ndisj){
85+
// See how many transitions there are
86+
unsigned int n = 0;
87+
for (unsigned int i = 0; i < ndisj; i++) {
88+
if (disj[i]->type == RE_DISJUNCTION) {
89+
assert(disj[i]->u.list.n > 1);
90+
n += disj[i]->u.list.n;
91+
}
92+
else {
93+
n++;
94+
}
95+
}
96+
8197
struct regexp *re = malloc(sizeof(*re));
8298
re->type = RE_DISJUNCTION;
83-
unsigned int size = sizeof(re) * ndisj;
84-
re->u.list.n = ndisj;
99+
unsigned int size = sizeof(re) * n;
100+
re->u.list.n = n;
85101
re->u.list.entries = malloc(size);
86-
memcpy(re->u.list.entries, disj, size);
102+
unsigned int j = 0;
103+
for (unsigned int i = 0; i < ndisj; i++) {
104+
if (disj[i]->type == RE_DISJUNCTION) {
105+
memcpy(&re->u.list.entries[j], disj[i]->u.list.entries,
106+
disj[i]->u.list.n * sizeof(re));
107+
j += disj[i]->u.list.n;
108+
}
109+
else {
110+
re->u.list.entries[j++] = disj[i];
111+
}
112+
}
87113
return re;
88114
}
89115

0 commit comments

Comments
 (0)