Solving conjunctive normal forms in C

时间:2016-04-04 18:06:46

标签: c linked-list conjunctive-normal-form

I'm seeking help for an assignment. I have to write (in C) an algorithm that solves a conjunctive normal formula (cnf) and after quite a few hours I can't make it work...

My program implements DPLL, and to be more precise, it is the part where I simplify my cnf, right after choosing a literal to instantiate, that causes me problem. I'm not sure if I am very clear so here is an example :

Formula : (a OR b) AND (not-a OR not-b) AND (not-a OR b)

Instantiation : a=TRUE b=FALSE

If I use my function simplify at this point, I should end up with (not-a OR b) being unsatisfied but it tells me that every clause is satisfied.

Here are the data-types I've defined (I used integers instead of chars for the literals, as it looked easier to manage) :

#define TRUE 1
#define FALSE 0
#define UNDEF -1

typedef int literal;

typedef int* interpretation;

typedef struct node {
    literal lit;
    struct node* next;
} * clause;

typedef struct _formula {
    clause c;
    struct _formula* next;
} * formula;

typedef struct _cnf {
    int nb_lit;
    formula f;
} * cnf;

And here is my simplify function

void simplify(cnf F, interpretation I) {
  clause pred, curr;
  int skip,b=FALSE;
  formula form, parentForm;
  form = F->f;
  parentForm = form;

  // Iterating through each clause of the formula
  while (form != NULL) {
    curr = form->c;
    pred = curr;
    skip = FALSE;
    while (curr != NULL && !skip) {
      b = FALSE;
      // If a literal appears as true and has benn interpreted as true
      if (curr->lit > 0 && I[curr->lit] == TRUE) {
        // We remove the current clause from the formula
        if (parentForm == form) {
          F->f = form->next;
          free(form);
          form = F->f;
          parentForm = form;
        } else {
          parentForm->next = form->next;
          free(form);
          form = parentForm->next;
        }
        skip = TRUE;
      }
      // Same goes with false
      if (curr->lit < 0 && I[-curr->lit] == FALSE) {
        if (parentForm == form) {
          F->f = form->next;
          free(form);
          form = F->f;
          parentForm = form;
        } else {
          parentForm->next = form->next;
          free(form);
          form = parentForm->next;
        }
        skip = TRUE;
      }

      // However if a literal appears as true and is interpreted as false (or
      // the opposite)
      if (curr->lit > 0 && I[curr->lit] == FALSE) {
        // We remove it from the clause
        if(pred == curr)
        {
          curr = curr->next;
          free(pred);
          form->c = curr;
          pred = curr;
          b=TRUE;
        }
        else
        {
          pred->next = curr->next;
          free(curr);
          pred = curr;
        }
      }
      else if (curr->lit < 0 && I[-curr->lit] == TRUE) {
        if(pred == curr)
        {
          curr = curr->next;
          free(pred);
          form->c = curr;
          pred = curr;
          b=TRUE;
        }
        else
        {
          pred->next = curr->next;
          free(curr);
          pred = curr;
        }
      }

      pred = curr;
      if(!b) curr = curr->next;
    }
    parentForm = form;
    if(!skip) form = form->next;
  }
}

I'm sorry for the long chunck of code, I don't know precisely what important part to focus on. I know several other problems remain, like the freeing of memory that is not complete (I think).

Apart from that, I have found several errors while trying to debug my problem, but I have the feeling that I create new ones while correcting old ones :/

Thx in advance if anyone can help me on this ! Also, I'm on windows 10, compiling with gcc through cygwin, if it's important :

gcc *.c

1 个答案:

答案 0 :(得分:1)

Also, I'm on windows 10, compiling with gcc through cygwin, if it's important

Actually it was... I was so sure it would have nothing to do with that that I didn't check earlier, and then while writing the post it didn't seem that unimportant anymore.

Anyway, I tried on a linux system and at first sight it seems to work fine.

Sorry for the inconvenience