Provide explanations for complex transformations.
Showing the changes to scripts (1 of 1 file). Show all
Unified · Split
| @@ -442,6 +442,7 @@ static struct expr *expr_join_or(struct expr *e1, struct expr *e2) · 441 unmodified lines | |||
| 442 | } | 442 | } |
| 443 | } | 443 | } |
| 444 | if (sym1->type == S_BOOLEAN) { | 444 | if (sym1->type == S_BOOLEAN) { |
| 445 | // a || !a -> y | ||
| 445 | if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || | 446 | if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || |
| 446 | (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) | 447 | (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) |
| 447 | return expr_alloc_symbol(&symbol_yes); | 448 | return expr_alloc_symbol(&symbol_yes); |
| @@ -647,6 +648,30 @@ struct expr *expr_eliminate_dups(struct expr *e) · 199 unmodified lines | |||
| 647 | * Performs various simplifications involving logical operators and | 648 | * Performs various simplifications involving logical operators and |
| 648 | * comparisons. | 649 | * comparisons. |
| 649 | * | 650 | * |
| 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 | * | ||
| 650 | * Allocates and returns a new expression. | 675 | * Allocates and returns a new expression. |
| 651 | */ | 676 | */ |
| 652 | struct expr *expr_transform(struct expr *e) | 677 | struct expr *expr_transform(struct expr *e) |
| @@ -674,12 +699,14 @@ struct expr *expr_transform(struct expr *e) · 21 unmodified lines | |||
| 674 | if (e->left.sym->type != S_BOOLEAN) | 699 | if (e->left.sym->type != S_BOOLEAN) |
| 675 | break; | 700 | break; |
| 676 | if (e->right.sym == &symbol_no) { | 701 | if (e->right.sym == &symbol_no) { |
| 702 | // A=n -> !A | ||
| 677 | e->type = E_NOT; | 703 | e->type = E_NOT; |
| 678 | e->left.expr = expr_alloc_symbol(e->left.sym); | 704 | e->left.expr = expr_alloc_symbol(e->left.sym); |
| 679 | e->right.sym = NULL; | 705 | e->right.sym = NULL; |
| 680 | break; | 706 | break; |
| 681 | } | 707 | } |
| 682 | if (e->right.sym == &symbol_mod) { | 708 | if (e->right.sym == &symbol_mod) { |
| 709 | // A=m -> n | ||
| 683 | printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); | 710 | printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); |
| 684 | e->type = E_SYMBOL; | 711 | e->type = E_SYMBOL; |
| 685 | e->left.sym = &symbol_no; | 712 | e->left.sym = &symbol_no; |
| @@ -687,6 +714,7 @@ struct expr *expr_transform(struct expr *e) · 1 unmodified line | |||
| 687 | break; | 714 | break; |
| 688 | } | 715 | } |
| 689 | if (e->right.sym == &symbol_yes) { | 716 | if (e->right.sym == &symbol_yes) { |
| 717 | // A=y -> A | ||
| 690 | e->type = E_SYMBOL; | 718 | e->type = E_SYMBOL; |
| 691 | e->right.sym = NULL; | 719 | e->right.sym = NULL; |
| 692 | break; | 720 | break; |
| @@ -696,11 +724,13 @@ struct expr *expr_transform(struct expr *e) · 3 unmodified lines | |||
| 696 | if (e->left.sym->type != S_BOOLEAN) | 724 | if (e->left.sym->type != S_BOOLEAN) |
| 697 | break; | 725 | break; |
| 698 | if (e->right.sym == &symbol_no) { | 726 | if (e->right.sym == &symbol_no) { |
| 727 | // A!=n -> A | ||
| 699 | e->type = E_SYMBOL; | 728 | e->type = E_SYMBOL; |
| 700 | e->right.sym = NULL; | 729 | e->right.sym = NULL; |
| 701 | break; | 730 | break; |
| 702 | } | 731 | } |
| 703 | if (e->right.sym == &symbol_mod) { | 732 | if (e->right.sym == &symbol_mod) { |
| 733 | // A!=m -> y | ||
| 704 | printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); | 734 | printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); |
| 705 | e->type = E_SYMBOL; | 735 | e->type = E_SYMBOL; |
| 706 | e->left.sym = &symbol_yes; | 736 | e->left.sym = &symbol_yes; |
| @@ -708,6 +738,7 @@ struct expr *expr_transform(struct expr *e) · 1 unmodified line | |||
| 708 | break; | 738 | break; |
| 709 | } | 739 | } |
| 710 | if (e->right.sym == &symbol_yes) { | 740 | if (e->right.sym == &symbol_yes) { |
| 741 | // A!=y -> !A | ||
| 711 | e->type = E_NOT; | 742 | e->type = E_NOT; |
| 712 | e->left.expr = expr_alloc_symbol(e->left.sym); | 743 | e->left.expr = expr_alloc_symbol(e->left.sym); |
| 713 | e->right.sym = NULL; | 744 | e->right.sym = NULL; |
| @@ -717,7 +748,7 @@ struct expr *expr_transform(struct expr *e) · 3 unmodified lines | |||
| 717 | case E_NOT: | 748 | case E_NOT: |
| 718 | switch (e->left.expr->type) { | 749 | switch (e->left.expr->type) { |
| 719 | case E_NOT: | 750 | case E_NOT: |
| 720 | // !!a -> a | 751 | // !!A -> A |
| 721 | tmp = e->left.expr->left.expr; | 752 | tmp = e->left.expr->left.expr; |
| 722 | free(e->left.expr); | 753 | free(e->left.expr); |
| 723 | free(e); | 754 | free(e); |
| @@ -726,7 +757,7 @@ struct expr *expr_transform(struct expr *e) · 2 unmodified lines | |||
| 726 | break; | 757 | break; |
| 727 | case E_EQUAL: | 758 | case E_EQUAL: |
| 728 | case E_UNEQUAL: | 759 | case E_UNEQUAL: |
| 729 | // !a='x' -> a!='x' | 760 | // !(A=B) -> A!=B |
| 730 | tmp = e->left.expr; | 761 | tmp = e->left.expr; |
| 731 | free(e); | 762 | free(e); |
| 732 | e = tmp; | 763 | e = tmp; |
| @@ -734,7 +765,7 @@ struct expr *expr_transform(struct expr *e) · 1 unmodified line | |||
| 734 | break; | 765 | break; |
| 735 | case E_LEQ: | 766 | case E_LEQ: |
| 736 | case E_GEQ: | 767 | case E_GEQ: |
| 737 | // !a<='x' -> a>'x' | 768 | // !(A<=B) -> A>B |
| 738 | tmp = e->left.expr; | 769 | tmp = e->left.expr; |
| 739 | free(e); | 770 | free(e); |
| 740 | e = tmp; | 771 | e = tmp; |
| @@ -742,14 +773,14 @@ struct expr *expr_transform(struct expr *e) · 1 unmodified line | |||
| 742 | break; | 773 | break; |
| 743 | case E_LTH: | 774 | case E_LTH: |
| 744 | case E_GTH: | 775 | case E_GTH: |
| 745 | // !a<'x' -> a>='x' | 776 | // !(A<B) -> A>=B |
| 746 | tmp = e->left.expr; | 777 | tmp = e->left.expr; |
| 747 | free(e); | 778 | free(e); |
| 748 | e = tmp; | 779 | e = tmp; |
| 749 | e->type = e->type == E_LTH ? E_GEQ : E_LEQ; | 780 | e->type = e->type == E_LTH ? E_GEQ : E_LEQ; |
| 750 | break; | 781 | break; |
| 751 | case E_OR: | 782 | case E_OR: |
| 752 | // !(a || b) -> !a && !b | 783 | // !(A || B) -> !A && !B |
| 753 | tmp = e->left.expr; | 784 | tmp = e->left.expr; |
| 754 | e->type = E_AND; | 785 | e->type = E_AND; |
| 755 | e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); | 786 | e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); |
| @@ -758,7 +789,7 @@ struct expr *expr_transform(struct expr *e) · 2 unmodified lines | |||
| 758 | e = expr_transform(e); | 789 | e = expr_transform(e); |
| 759 | break; | 790 | break; |
| 760 | case E_AND: | 791 | case E_AND: |
| 761 | // !(a && b) -> !a || !b | 792 | // !(A && B) -> !A || !B |
| 762 | tmp = e->left.expr; | 793 | tmp = e->left.expr; |
| 763 | e->type = E_OR; | 794 | e->type = E_OR; |
| 764 | e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); | 795 | e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); |