Node * push_negation(Node *n) { Node *m; Assert(n->ntyp == NOT, n->ntyp); switch (n->lft->ntyp) { case TRUE: releasenode(0, n->lft); n->lft = ZN; n->ntyp = FALSE; break; case FALSE: releasenode(0, n->lft); n->lft = ZN; n->ntyp = TRUE; break; case NOT: m = n->lft->lft; releasenode(0, n->lft); n->lft = ZN; releasenode(0, n); n = m; break; case V_OPER: n->ntyp = U_OPER; goto same; case U_OPER: n->ntyp = V_OPER; goto same; #ifdef NXT case NEXT: n->ntyp = NEXT; n->lft->ntyp = NOT; n->lft = push_negation(n->lft); break; #endif case AND: n->ntyp = OR; goto same; case OR: n->ntyp = AND; same: m = n->lft->rgt; n->lft->rgt = ZN; n->rgt = Not(m); n->lft->ntyp = NOT; m = n->lft; n->lft = push_negation(m); break; } return rewrite(n); }
Node *switchNotTempOper(Node *n, int ntyp, Miscellaneous *miscell, int *cnt, char *uform, int *tl_yychar) { Node *m; m = n; n = n->lft; n->ntyp = ntyp; m->lft = n->lft; n->lft = push_negation(m, miscell, cnt, uform, tl_yychar); if (ntyp!=NEXT && ntyp!=WEAKNEXT) { n->rgt = Not(n->rgt); } return(n); }
Node *switchNotTempOper(Node *n, int ntyp) { Node *m; m = n; n = n->lft; n->ntyp = ntyp; m->lft = n->lft; n->lft = push_negation(m); if (ntyp!=NEXT && ntyp!=WEAKNEXT) { n->rgt = Not(n->rgt); } return(n); }
static Node * tl_factor(void) { Node *ptr = ZN; switch (tl_yychar) { case '(': ptr = tl_formula(); if (tl_yychar != ')') tl_yyerror("expected ')'"); tl_yychar = tl_yylex(); break; case NOT: ptr = tl_yylval; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); if (!ptr->lft) { fatal("malformed expression", (char *) 0); } ptr = push_negation(ptr); break; case ALWAYS: tl_yychar = tl_yylex(); ptr = tl_factor(); #ifndef NO_OPT if (ptr->ntyp == FALSE || ptr->ntyp == TRUE) break; /* [] false == false */ if (ptr->ntyp == V_OPER) { if (ptr->lft->ntyp == FALSE) break; /* [][]p = []p */ ptr = ptr->rgt; /* [] (p V q) = [] q */ } #endif ptr = tl_nn(V_OPER, False, ptr); break; #ifdef NXT case NEXT: tl_yychar = tl_yylex(); ptr = tl_factor(); if (ptr->ntyp == TRUE) break; /* X true = true */ ptr = tl_nn(NEXT, ptr, ZN); break; #endif case CEXPR: tl_yychar = tl_yylex(); ptr = tl_factor(); if (ptr->ntyp != PREDICATE) { tl_yyerror("expected {...} after c_expr"); } ptr = tl_nn(CEXPR, ptr, ZN); break; case EVENTUALLY: tl_yychar = tl_yylex(); ptr = tl_factor(); #ifndef NO_OPT if (ptr->ntyp == TRUE || ptr->ntyp == FALSE) break; /* <> true == true */ if (ptr->ntyp == U_OPER && ptr->lft->ntyp == TRUE) break; /* <><>p = <>p */ if (ptr->ntyp == U_OPER) { /* <> (p U q) = <> q */ ptr = ptr->rgt; /* fall thru */ } #endif ptr = tl_nn(U_OPER, True, ptr); break; case PREDICATE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; case TRUE: case FALSE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; } if (!ptr) tl_yyerror("expected predicate"); #if 0 printf("factor: "); tl_explain(ptr->ntyp); printf("\n"); #endif return ptr; }
Node * push_negation(Node *n) { Node *m; Assert(n->ntyp == NOT, n->ntyp); switch (n->lft->ntyp) { case TRUE: Debug("!true => false\n"); releasenode(0, n->lft); n->lft = ZN; n->ntyp = FALSE; break; case FALSE: Debug("!false => true\n"); releasenode(0, n->lft); n->lft = ZN; n->ntyp = TRUE; break; case NOT: Debug("!!p => p\n"); m = n->lft->lft; releasenode(0, n->lft); n->lft = ZN; releasenode(0, n); n = m; break; case V_OPER: Debug("!(p V q) => (!p U !q)\n"); n->ntyp = U_OPER; goto same; case U_OPER: Debug("!(p U q) => (!p V !q)\n"); n->ntyp = V_OPER; goto same; #ifdef NXT case NEXT: Debug("!X -> X!\n"); n->ntyp = NEXT; n->lft->ntyp = NOT; n->lft = push_negation(n->lft); break; #endif case AND: Debug("!(p && q) => !p || !q\n"); n->ntyp = OR; goto same; case OR: Debug("!(p || q) => !p && !q\n"); n->ntyp = AND; same: m = n->lft->rgt; n->lft->rgt = ZN; n->rgt = Not(m); n->lft->ntyp = NOT; m = n->lft; n->lft = push_negation(m); break; } return rewrite(n); }
static Node *bin_simpler(Node *ptr) { 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)) /* NEW */ { ptr = ptr->rgt; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->lft, ptr->rgt)) { /* (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)) { /* 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), ZN); 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), ZN); 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)), ptr->lft)) { 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)) { /* 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), ZN); 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)) { ptr = ptr->rgt; break; } /* NEW */ if (ptr->lft->ntyp != FALSE && implies(ptr->lft, push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN)))) { 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) { ptr = ptr->lft; 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) { ptr = ptr->lft; break; } break; case IMPLIES: if (implies(ptr->lft, ptr->rgt)) { ptr = True; break; } ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt); ptr = rewrite(ptr); break; case EQUIV: if (implies(ptr->lft, ptr->rgt) && implies(ptr->rgt, ptr->lft)) { ptr = True; break; } a = rewrite(tl_nn(AND, dupnode(ptr->lft), dupnode(ptr->rgt))); b = rewrite(tl_nn(AND, Not(ptr->lft), Not(ptr->rgt))); ptr = tl_nn(OR, a, b); ptr = rewrite(ptr); break; case AND: /* p && (q U p) = p */ if (ptr->rgt->ntyp == U_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->lft; break; } if (ptr->lft->ntyp == U_OPER && isequal(ptr->lft->rgt, ptr->rgt)) { ptr = ptr->rgt; break; } /* p && (q V p) == q V p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { ptr = ptr->rgt; break; } if (ptr->lft->ntyp == V_OPER && isequal(ptr->lft->rgt, ptr->rgt)) { 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)) { ptr = tl_nn(U_OPER, tl_nn(AND, ptr->lft->lft, ptr->rgt->lft), ptr->lft->rgt); 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)) { ptr = tl_nn(V_OPER, ptr->rgt->lft, tl_nn(AND, ptr->lft->rgt, ptr->rgt->rgt)); 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), ZN); 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)) { ptr = ptr->lft; break; } if (isequal(ptr->lft, ptr->rgt) /* (p && p) == p */ || ptr->rgt->ntyp == FALSE /* (p && F) == F */ || ptr->lft->ntyp == TRUE /* (T && p) == p */ || implies(ptr->rgt, ptr->lft))/* 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))/* 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))); break; } /* NEW */ if (implies(ptr->lft, push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN))) || implies(ptr->rgt, push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN)))) { 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)) { ptr = ptr->rgt; break; } /* p || (q V p) == p */ if (ptr->rgt->ntyp == V_OPER && isequal(ptr->rgt->rgt, ptr->lft)) { 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)) { ptr = tl_nn(U_OPER, ptr->rgt->lft, tl_nn(OR, ptr->lft->rgt, ptr->rgt->rgt)); break; } if (isequal(ptr->lft, ptr->rgt) /* (p || p) == p */ || ptr->rgt->ntyp == FALSE /* (p || F) == p */ || ptr->lft->ntyp == TRUE /* (T || p) == T */ || implies(ptr->rgt, ptr->lft))/* 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))/* 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)) { ptr = tl_nn(V_OPER, tl_nn(OR, ptr->lft->lft, ptr->rgt->lft), ptr->rgt->rgt); 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)) { 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))); break; } /* NEW */ if (implies(push_negation(tl_nn(NOT, dupnode(ptr->rgt), ZN)), ptr->lft) || implies(push_negation(tl_nn(NOT, dupnode(ptr->lft), ZN)), ptr->rgt)) { ptr = True; break; } break; } return ptr; }
static Node *tl_factor(void) { Node *ptr = ZN; switch (tl_yychar) { case '(': ptr = tl_formula(); if (tl_yychar != ')') tl_yyerror("expected ')'"); tl_yychar = tl_yylex(); goto simpl; case NOT: ptr = tl_yylval; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); ptr = push_negation(ptr); goto simpl; case ALWAYS: ptr = tl_nn(V_OPER, False, ptr); ptr->time = TimeCon; tl_yychar = tl_yylex(); ptr->rgt = tl_factor(); if(tl_simp_log) { /* must be modified! */ if (ptr->ntyp == V_OPER) { if (ptr->lft->ntyp == FALSE) break; /* [][]p = []p */ ptr = ptr->rgt; /* [] (p V q) = [] q */ } } goto simpl; case NEXT: ptr = tl_nn(NEXT, ZN, ZN); ptr->time = TimeCon; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); goto simpl; case WEAKNEXT: ptr = tl_nn(WEAKNEXT, ZN, ZN); ptr->time = TimeCon; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); goto simpl; case EVENTUALLY: ptr = tl_nn(U_OPER, True, ZN); ptr->time = TimeCon; tl_yychar = tl_yylex(); ptr->rgt = tl_factor(); if(tl_simp_log) { /* this must be modified */ if (ptr->ntyp == U_OPER && ptr->lft->ntyp == TRUE) break; /* <><>p = <>p */ if (ptr->ntyp == U_OPER) { /* <> (p U q) = <> q */ ptr = ptr->rgt; /* fall thru */ } } /* goto simpl; case IMPLIES: ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt); goto simpl; case EQUIV: a = tl_nn(AND,dupnode(ptr->lft),dupnode(ptr->rgt)); b = tl_nn(AND,Not(ptr->lft),Not(ptr->rgt)); ptr = tl_nn(OR, a, b); */ simpl: if (tl_simp_log) ptr = bin_simpler(ptr); break; case PREDICATE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; case TRUE: case FALSE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; } if (!ptr) tl_yyerror("expected predicate"); #if 0 printf("factor: "); tl_explain(ptr->ntyp); printf("\n"); #endif return ptr; }
static Node * tl_factor(void) { Node *ptr = ZN; switch (tl_yychar) { case '(': ptr = tl_formula(); if (tl_yychar != ')') tl_yyerror("expected ')'"); tl_yychar = tl_yylex(); goto simpl; case NOT: ptr = tl_yylval; tl_yychar = tl_yylex(); ptr->lft = tl_factor(); ptr = push_negation(ptr); goto simpl; case ALWAYS: tl_yychar = tl_yylex(); ptr = tl_factor(); if(tl_simp_log) { if (ptr->ntyp == FALSE || ptr->ntyp == TRUE) break; /* [] false == false */ if (ptr->ntyp == V_OPER) { if (ptr->lft->ntyp == FALSE) break; /* [][]p = []p */ ptr = ptr->rgt; /* [] (p V q) = [] q */ } } ptr = tl_nn(V_OPER, False, ptr); goto simpl; #ifdef NXT case NEXT: tl_yychar = tl_yylex(); ptr = tl_factor(); if ((ptr->ntyp == TRUE || ptr->ntyp == FALSE)&& tl_simp_log) break; /* X true = true , X false = false */ ptr = tl_nn(NEXT, ptr, ZN); goto simpl; #endif case EVENTUALLY: tl_yychar = tl_yylex(); ptr = tl_factor(); if(tl_simp_log) { if (ptr->ntyp == TRUE || ptr->ntyp == FALSE) break; /* <> true == true */ if (ptr->ntyp == U_OPER && ptr->lft->ntyp == TRUE) break; /* <><>p = <>p */ if (ptr->ntyp == U_OPER) { /* <> (p U q) = <> q */ ptr = ptr->rgt; /* fall thru */ } } ptr = tl_nn(U_OPER, True, ptr); simpl: if (tl_simp_log) ptr = bin_simpler(ptr); break; case PREDICATE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; case TRUE: case FALSE: ptr = tl_yylval; tl_yychar = tl_yylex(); break; } if (!ptr) tl_yyerror("expected predicate"); #if 0 printf("factor: "); tl_explain(ptr->ntyp); printf("\n"); #endif return ptr; }
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; }
static Node *tl_factor(int *cnt, size_t hasuform, char *uform, Miscellaneous *miscell, int *tl_yychar) { Node *ptr = ZN; int tl_simp_log_p = 0; switch ((*tl_yychar)) { case '(': ptr = tl_formula(cnt, hasuform, uform, miscell, tl_yychar); if ((*tl_yychar) != ')') tl_yyerror("expected ')'", cnt, uform, tl_yychar, miscell); (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); goto simpl; case NOT: ptr = miscell->tl_yylval; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); ptr->lft = tl_factor(cnt, hasuform, uform, miscell, tl_yychar); ptr = push_negation(ptr, miscell, cnt, uform, tl_yychar); goto simpl; case ALWAYS: ptr = tl_nn(ALWAYS, False, ZN, miscell); ptr->time = miscell->TimeCon; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); ptr->rgt = tl_factor(cnt, hasuform, uform, miscell, tl_yychar); goto simpl; case NEXT: ptr = tl_nn(NEXT, ZN, ZN, miscell); ptr->time = miscell->TimeCon; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); ptr->lft = tl_factor(cnt, hasuform, uform, miscell, tl_yychar); goto simpl; case WEAKNEXT: ptr = tl_nn(WEAKNEXT, ZN, ZN, miscell); ptr->time = miscell->TimeCon; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); ptr->lft = tl_factor(cnt, hasuform, uform, miscell, tl_yychar); goto simpl; case EVENTUALLY: ptr = tl_nn(EVENTUALLY, True, ZN, miscell); ptr->time = miscell->TimeCon; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); ptr->rgt = tl_factor(cnt, hasuform, uform, miscell, tl_yychar); goto simpl; /* case IMPLIES: ptr = tl_nn(OR, Not(ptr->lft), ptr->rgt); goto simpl; /* case EQUIV: a = tl_nn(AND,dupnode(ptr->lft),dupnode(ptr->rgt)); b = tl_nn(AND,Not(ptr->lft),Not(ptr->rgt)); ptr = tl_nn(OR, a, b); */ simpl: if (tl_simp_log_p) ptr = bin_simpler(ptr,miscell,cnt,uform, tl_yychar); break; case PREDICATE: ptr = miscell->tl_yylval; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); break; case TRUE: case FALSE: ptr = miscell->tl_yylval; (*tl_yychar) = tl_yylex(cnt, hasuform, uform, miscell, tl_yychar); break; } if (!ptr) tl_yyerror("expected predicate", cnt, uform, tl_yychar, miscell); #if 0 printf("factor: "); tl_explain(ptr->ntyp); printf("\n"); #endif return ptr; }