Node * right_linked(Node *n) { if (!n) return n; if (n->ntyp == AND || n->ntyp == OR) while (n->lft && n->lft->ntyp == n->ntyp) { Node *tmp = n->lft; n->lft = tmp->rgt; tmp->rgt = n; n = tmp; } n->lft = right_linked(n->lft); n->rgt = right_linked(n->rgt); return n; }
static void mk_red(Node *n) { Graph *p; n = right_linked(n); for (p = Nodes_Set; p; p = p->nxt) { if (p->outgoing && has_clause(0, p, n)) { if (p->redcnt >= 63) Fatal("too many Untils", (char *)0); p->isred[p->redcnt++] = (unsigned char) Red_cnt; Lab_cnt++; Max_Red = Red_cnt; } } }
static void mk_grn(Node *n) { Graph *p; n = right_linked(n); more: for (p = Nodes_Set; p; p = p->nxt) if (p->outgoing && has_clause(AND, p, n)) { p->isgrn[p->grncnt++] = (unsigned char) Red_cnt; Lab_cnt++; } if (n->ntyp == U_OPER) /* 3.4.0 */ { n = n->rgt; goto more; } }
static int has_clause(int tok, Graph *p, Node *n) { Node *q, *qq; switch (n->ntyp) { case AND: return has_clause(tok, p, n->lft) && has_clause(tok, p, n->rgt); case OR: return has_clause(tok, p, n->lft) || has_clause(tok, p, n->rgt); } for (q = p->Other; q; q = q->nxt) { qq = right_linked(q); if (anywhere(tok, n, qq)) return 1; } return 0; }
static Node *bin_simpler(Node *ptr, Miscellaneous *miscell, int *cnt, char *uform, int *tl_yychar) { Node *a, *b; if (ptr) switch (ptr->ntyp) { case U_OPER: if (ptr->rgt->ntyp == TRUE || ptr->rgt->ntyp == FALSE || ptr->lft->ntyp == FALSE) { ptr = ptr->rgt; break; } if (implies(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell)) /* NEW */ { ptr = ptr->rgt; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->lft, ptr->rgt, cnt, uform, tl_yychar, miscell)) { /* (p U q) U p = (q U p) */ ptr->lft = ptr->lft->rgt; break; } if (ptr->rgt->ntyp == U_OPER && implies(ptr->lft, ptr->rgt->lft, cnt, uform, tl_yychar, miscell)) { /* NEW */ ptr = ptr->rgt; break; } /* X p U X q == X (p U q) */ if (ptr->rgt->ntyp == NEXT && ptr->lft->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(U_OPER, ptr->lft->lft, ptr->rgt->lft, miscell), ZN, miscell); break; } /* NEW : F X p == X F p */ if (ptr->lft->ntyp == TRUE && ptr->rgt->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(U_OPER, True, ptr->rgt->lft, miscell), ZN, miscell); break; } /* NEW : F G F p == G F p */ if (ptr->lft->ntyp == TRUE && ptr->rgt->ntyp == V_OPER && ptr->rgt->lft->ntyp == FALSE && ptr->rgt->rgt->ntyp == U_OPER && ptr->rgt->rgt->lft->ntyp == TRUE) { ptr = ptr->rgt; break; } /* NEW */ if (ptr->lft->ntyp != TRUE && implies(push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN, miscell), miscell, cnt, uform, tl_yychar), ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr->lft = True; break; } break; case V_OPER: if (ptr->rgt->ntyp == FALSE || ptr->rgt->ntyp == TRUE || ptr->lft->ntyp == TRUE) { ptr = ptr->rgt; break; } if (implies(ptr->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { /* p V p = p */ ptr = ptr->rgt; break; } /* F V (p V q) == F V q */ if (ptr->lft->ntyp == FALSE && ptr->rgt->ntyp == V_OPER) { ptr->rgt = ptr->rgt->rgt; break; } /* NEW : G X p == X G p */ if (ptr->lft->ntyp == FALSE && ptr->rgt->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(V_OPER, False, ptr->rgt->lft, miscell), ZN, miscell); break; } /* NEW : G F G p == F G p */ if (ptr->lft->ntyp == FALSE && ptr->rgt->ntyp == U_OPER && ptr->rgt->lft->ntyp == TRUE && ptr->rgt->rgt->ntyp == V_OPER && ptr->rgt->rgt->lft->ntyp == FALSE) { ptr = ptr->rgt; break; } /* NEW */ if (ptr->rgt->ntyp == V_OPER && implies(ptr->rgt->lft, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = ptr->rgt; break; } /* NEW */ if (ptr->lft->ntyp != FALSE && implies(ptr->lft, push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN, miscell), miscell, cnt, uform, tl_yychar), cnt, uform, tl_yychar, miscell)) { ptr->lft = False; break; } break; case NEXT: /* NEW : X G F p == G F p */ if (ptr->lft->ntyp == V_OPER && ptr->lft->lft->ntyp == FALSE && ptr->lft->rgt->ntyp == U_OPER && ptr->lft->rgt->lft->ntyp == TRUE) { break; } /* NEW : X F G p == F G p */ if (ptr->lft->ntyp == U_OPER && ptr->lft->lft->ntyp == TRUE && ptr->lft->rgt->ntyp == V_OPER && ptr->lft->rgt->lft->ntyp == FALSE) { break; } break; case ALWAYS: /* NEW : [] G F p == G F p */ if (ptr->rgt->ntyp == V_OPER && ptr->rgt->rgt->ntyp == FALSE && ptr->rgt->lft->ntyp == U_OPER && ptr->rgt->lft->rgt->ntyp == TRUE) { ptr = ptr->rgt; break; } /* NEW : [] F G p == F G p */ if (ptr->rgt->ntyp == U_OPER && ptr->rgt->rgt->ntyp == TRUE && ptr->rgt->lft->ntyp == V_OPER && ptr->rgt->lft->rgt->ntyp == FALSE) { ptr = ptr->rgt; break; } break; case IMPLIES: if (implies(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell)) { ptr = True; break; } ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt, miscell); ptr = canonical(right_linked(ptr), miscell, cnt, uform, tl_yychar); break; case EQUIV: if (implies(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell) && implies(ptr->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = True; break; } a = canonical(right_linked(tl_nn(AND, dupnode(ptr->lft), dupnode(ptr->rgt), miscell)), miscell, cnt, uform, tl_yychar); b = canonical(right_linked(tl_nn(AND, Not(ptr->lft), Not(ptr->rgt), miscell)), miscell, cnt, uform, tl_yychar); ptr = tl_nn(OR, a, b, miscell); ptr = canonical(right_linked(ptr), miscell, cnt, uform, tl_yychar); break; case AND: /* p && (q U p) = p */ if (ptr->rgt->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = ptr->lft; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->rgt, ptr->rgt, cnt, uform, tl_yychar, miscell)) { ptr = ptr->rgt; break; } /* p && (q V p) == q V p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = ptr->rgt; break; } if (ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt, cnt, uform, tl_yychar, miscell)) { ptr = ptr->lft; break; } /* (p U q) && (r U q) = (p && r) U q*/ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft->rgt, cnt, uform, tl_yychar, miscell)) { ptr = tl_nn(U_OPER, tl_nn(AND, ptr->lft->lft, ptr->rgt->lft, miscell), ptr->lft->rgt, miscell); break; } /* (p V q) && (p V r) = p V (q && r) */ if (ptr->rgt->ntyp == V_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->rgt->lft, ptr->lft->lft, cnt, uform, tl_yychar, miscell)) { ptr = tl_nn(V_OPER, ptr->rgt->lft, tl_nn(AND, ptr->lft->rgt, ptr->rgt->rgt, miscell), miscell); break; } /* X p && X q == X (p && q) */ if (ptr->rgt->ntyp == NEXT && ptr->lft->ntyp == NEXT) { ptr = tl_nn(NEXT, tl_nn(AND, ptr->rgt->lft, ptr->lft->lft, miscell), ZN, miscell); break; } /* (p V q) && (r U q) == p V q */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt, cnt, uform, tl_yychar, miscell)) { ptr = ptr->lft; break; } if (isequal(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell) /* (p && p) == p */ || ptr->rgt->ntyp == FALSE /* (p && F) == F */ || ptr->lft->ntyp == TRUE /* (T && p) == p */ || implies(ptr->rgt, ptr->lft, cnt, uform, tl_yychar, miscell))/* NEW */ { ptr = ptr->rgt; break; } if (ptr->rgt->ntyp == TRUE /* (p && T) == p */ || ptr->lft->ntyp == FALSE /* (F && p) == F */ || implies(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell))/* NEW */ { ptr = ptr->lft; break; } /* NEW : F G p && F G q == F G (p && q) */ if (ptr->lft->ntyp == U_OPER && ptr->lft->lft->ntyp == TRUE && ptr->lft->rgt->ntyp == V_OPER && ptr->lft->rgt->lft->ntyp == FALSE && ptr->rgt->ntyp == U_OPER && ptr->rgt->lft->ntyp == TRUE && ptr->rgt->rgt->ntyp == V_OPER && ptr->rgt->rgt->lft->ntyp == FALSE) { ptr = tl_nn(U_OPER, True, tl_nn(V_OPER, False, tl_nn(AND, ptr->lft->rgt->rgt, ptr->rgt->rgt->rgt, miscell), miscell), miscell); break; } /* NEW */ if (implies(ptr->lft, push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN, miscell), miscell, cnt, uform, tl_yychar), cnt, uform, tl_yychar, miscell) || implies(ptr->rgt, push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN, miscell), miscell, cnt, uform, tl_yychar), cnt, uform, tl_yychar, miscell)) { ptr = False; break; } break; case OR: /* p || (q U p) == q U p */ if (ptr->rgt->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = ptr->rgt; break; } /* p || (q V p) == p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft, cnt, uform, tl_yychar, miscell)) { ptr = ptr->lft; break; } /* (p U q) || (p U r) = p U (q || r) */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == U_OPER && isequal(ptr->rgt->lft, ptr->lft->lft, cnt, uform, tl_yychar, miscell)) { ptr = tl_nn(U_OPER, ptr->rgt->lft, tl_nn(OR, ptr->lft->rgt, ptr->rgt->rgt, miscell), miscell); break; } if (isequal(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell) /* (p || p) == p */ || ptr->rgt->ntyp == FALSE /* (p || F) == p */ || ptr->lft->ntyp == TRUE /* (T || p) == T */ || implies(ptr->rgt, ptr->lft, cnt, uform, tl_yychar, miscell))/* NEW */ { ptr = ptr->lft; break; } if (ptr->rgt->ntyp == TRUE /* (p || T) == T */ || ptr->lft->ntyp == FALSE /* (F || p) == p */ || implies(ptr->lft, ptr->rgt, cnt, uform, tl_yychar, miscell))/* NEW */ { ptr = ptr->rgt; break; } /* (p V q) || (r V q) = (p || r) V q */ if (ptr->rgt->ntyp == V_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt, cnt, uform, tl_yychar, miscell)) { ptr = tl_nn(V_OPER, tl_nn(OR, ptr->lft->lft, ptr->rgt->lft, miscell), ptr->rgt->rgt, miscell); break; } /* (p V q) || (r U q) == r U q */ if (ptr->rgt->ntyp == U_OPER && ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt->rgt, cnt, uform, tl_yychar, miscell)) { ptr = ptr->rgt; break; } /* NEW : G F p || G F q == G F (p || q) */ if (ptr->lft->ntyp == V_OPER && ptr->lft->lft->ntyp == FALSE && ptr->lft->rgt->ntyp == U_OPER && ptr->lft->rgt->lft->ntyp == TRUE && ptr->rgt->ntyp == V_OPER && ptr->rgt->lft->ntyp == FALSE && ptr->rgt->rgt->ntyp == U_OPER && ptr->rgt->rgt->lft->ntyp == TRUE) { ptr = tl_nn(V_OPER, False, tl_nn(U_OPER, True, tl_nn(OR, ptr->lft->rgt->rgt, ptr->rgt->rgt->rgt, miscell), miscell), miscell); break; } /* NEW */ if (implies(push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN, miscell), miscell, cnt, uform, tl_yychar), ptr->lft, cnt, uform, tl_yychar, miscell) || implies(push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN, miscell), miscell, cnt, uform, tl_yychar), ptr->rgt, cnt, uform, tl_yychar, miscell)) { ptr = True; break; } break; } return ptr; }