tybalt89 discovered a bug in Fun with logical expressions:

$ echo IEabEba | perl try.pl ORIG: IEabEba MOD: V~V~V~a~b;~V~~a~~b;;V~V~b~a;~V~~b~~a;;; ...> V~V~V~a~b;~Vab;;V~V~b~a;~Vba;;; ...> V~V~V~a~b;~Vab;;~V~b~a;~Vba;; Not a tautology

(a equals b) implies (b equals a) is a tautology but the program fails to recognize it. With the fixed code below it generates this output instead:

$ echo IEabEba | perl taut.pl ORIG: IEabEba MOD: V~V~V~a~b;~V~~a~~b;;V~V~b~a;~V~~b~~a;;; ...> V~V~V~a~b;~Vab;;V~V~b~a;~Vba;;; ...> V~V~V~a~b;~Vab;;~V~b~a;~Vba;; ...> V~Vba;~V~V~a~b;~Vab;;~V~b~a;; ...> V~Vab;~V~Vab;~V~a~b;;~V~a~b;; ...> V~Vab;~V0~V~a~b;;~V~a~b;; ...> V~Vab;~V~V~a~b;;~V~a~b;; ...> V~Vab;~~V~a~b;~V~a~b;; ...> V~Vab;V~a~b;~V~a~b;; ...> V~Vab;~a~b~V~a~b;; ...> V~Vab;~a~b~V0~b;; ...> V~Vab;~a~b~V~b;; ...> V~Vab;~a~b~~b; ...> V~Vab;~a~bb; ...> V~V1b;~a~bb; ...> V~1~a~bb; ...> V0~a~bb; ...> V~a~bb; ...> V~a~b1; ...> 1 Tautology

The following changes were made to the code:

The "regex libraries" $rawlib and $modlib and their named subpatterns (?&rawexpr) and (?&exp) are gone. They were replaced by $rawexpr and $exp , subregexes that directly match and capture a simplifed and modified expression, respectively. This change was made in order to make it possible to split a string into subexpressions using my @expr = $str =~ /$exp/g (i.e. m//g in list context). Two regexes were simplified by using \K . The old "final rule" did some duplicate work: It used index($1, $3) < 0 && index($4, $3) < 0 inside the regex to search for the subexpression $3 in both $1 and $4 . If successful, it repeated the search in the replacement part: s{ \Q$x\E }{$spec}g for $pre, $post; The new version uses s/// directly in the regex and checks the return value to see if any match was found/replaced. The replacement string is assembled directly in the regex and saved in an outer lexical variable to make it available in the right-hand side. A new rule was added. If the other rules get stuck, it reorders V operands. The canonical order chosen is simply the default sort behavior: lexicographically ascending strings.

Due to change #3 and #4 the code no longer works on old perls (before v5.18) because in v5.18 the implementation of embedded code blocks in regexes was rewritten, fixing many bugs.

The new code: