@@ -442,6 +442,7 @@ static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
442442 }
443443 }
444444 if (sym1 -> type == S_BOOLEAN ) {
445+ // a || !a -> y
445446 if ((e1 -> type == E_NOT && e1 -> left .expr -> type == E_SYMBOL && e2 -> type == E_SYMBOL ) ||
446447 (e2 -> type == E_NOT && e2 -> left .expr -> type == E_SYMBOL && e1 -> type == E_SYMBOL ))
447448 return expr_alloc_symbol (& symbol_yes );
@@ -647,6 +648,30 @@ struct expr *expr_eliminate_dups(struct expr *e)
647648 * Performs various simplifications involving logical operators and
648649 * comparisons.
649650 *
651+ * For bool type:
652+ * A=n -> !A
653+ * A=m -> n
654+ * A=y -> A
655+ * A!=n -> A
656+ * A!=m -> y
657+ * A!=y -> !A
658+ *
659+ * For any type:
660+ * !!A -> A
661+ * !(A=B) -> A!=B
662+ * !(A!=B) -> A=B
663+ * !(A<=B) -> A>B
664+ * !(A>=B) -> A<B
665+ * !(A<B) -> A>=B
666+ * !(A>B) -> A<=B
667+ * !(A || B) -> !A && !B
668+ * !(A && B) -> !A || !B
669+ *
670+ * For constant:
671+ * !y -> n
672+ * !m -> m
673+ * !n -> y
674+ *
650675 * Allocates and returns a new expression.
651676 */
652677struct expr * expr_transform (struct expr * e )
@@ -674,19 +699,22 @@ struct expr *expr_transform(struct expr *e)
674699 if (e -> left .sym -> type != S_BOOLEAN )
675700 break ;
676701 if (e -> right .sym == & symbol_no ) {
702+ // A=n -> !A
677703 e -> type = E_NOT ;
678704 e -> left .expr = expr_alloc_symbol (e -> left .sym );
679705 e -> right .sym = NULL ;
680706 break ;
681707 }
682708 if (e -> right .sym == & symbol_mod ) {
709+ // A=m -> n
683710 printf ("boolean symbol %s tested for 'm'? test forced to 'n'\n" , e -> left .sym -> name );
684711 e -> type = E_SYMBOL ;
685712 e -> left .sym = & symbol_no ;
686713 e -> right .sym = NULL ;
687714 break ;
688715 }
689716 if (e -> right .sym == & symbol_yes ) {
717+ // A=y -> A
690718 e -> type = E_SYMBOL ;
691719 e -> right .sym = NULL ;
692720 break ;
@@ -696,18 +724,21 @@ struct expr *expr_transform(struct expr *e)
696724 if (e -> left .sym -> type != S_BOOLEAN )
697725 break ;
698726 if (e -> right .sym == & symbol_no ) {
727+ // A!=n -> A
699728 e -> type = E_SYMBOL ;
700729 e -> right .sym = NULL ;
701730 break ;
702731 }
703732 if (e -> right .sym == & symbol_mod ) {
733+ // A!=m -> y
704734 printf ("boolean symbol %s tested for 'm'? test forced to 'y'\n" , e -> left .sym -> name );
705735 e -> type = E_SYMBOL ;
706736 e -> left .sym = & symbol_yes ;
707737 e -> right .sym = NULL ;
708738 break ;
709739 }
710740 if (e -> right .sym == & symbol_yes ) {
741+ // A!=y -> !A
711742 e -> type = E_NOT ;
712743 e -> left .expr = expr_alloc_symbol (e -> left .sym );
713744 e -> right .sym = NULL ;
@@ -717,7 +748,7 @@ struct expr *expr_transform(struct expr *e)
717748 case E_NOT :
718749 switch (e -> left .expr -> type ) {
719750 case E_NOT :
720- // !!a -> a
751+ // !!A -> A
721752 tmp = e -> left .expr -> left .expr ;
722753 free (e -> left .expr );
723754 free (e );
@@ -726,30 +757,30 @@ struct expr *expr_transform(struct expr *e)
726757 break ;
727758 case E_EQUAL :
728759 case E_UNEQUAL :
729- // !a='x' -> a!='x'
760+ // !(A=B) -> A!=B
730761 tmp = e -> left .expr ;
731762 free (e );
732763 e = tmp ;
733764 e -> type = e -> type == E_EQUAL ? E_UNEQUAL : E_EQUAL ;
734765 break ;
735766 case E_LEQ :
736767 case E_GEQ :
737- // !a<='x' -> a>'x'
768+ // !(A<=B) -> A>B
738769 tmp = e -> left .expr ;
739770 free (e );
740771 e = tmp ;
741772 e -> type = e -> type == E_LEQ ? E_GTH : E_LTH ;
742773 break ;
743774 case E_LTH :
744775 case E_GTH :
745- // !a<'x' -> a>='x'
776+ // !(A<B) -> A>=B
746777 tmp = e -> left .expr ;
747778 free (e );
748779 e = tmp ;
749780 e -> type = e -> type == E_LTH ? E_GEQ : E_LEQ ;
750781 break ;
751782 case E_OR :
752- // !(a || b ) -> !a && !b
783+ // !(A || B ) -> !A && !B
753784 tmp = e -> left .expr ;
754785 e -> type = E_AND ;
755786 e -> right .expr = expr_alloc_one (E_NOT , tmp -> right .expr );
@@ -758,7 +789,7 @@ struct expr *expr_transform(struct expr *e)
758789 e = expr_transform (e );
759790 break ;
760791 case E_AND :
761- // !(a && b ) -> !a || !b
792+ // !(A && B ) -> !A || !B
762793 tmp = e -> left .expr ;
763794 e -> type = E_OR ;
764795 e -> right .expr = expr_alloc_one (E_NOT , tmp -> right .expr );
0 commit comments