# Regular Expression for logical implication?

I am massively unfamiliar with the usage and syntax of regular expressions so the following problem is making my brain bleed.

Background: I am taking logical expressions, parsing them, making some replacements, and then evaluating them using \fp_eval:n. For example,

-a*(b+c)--1-> !a&&(b||c)--2-> !0&&(1||0)--3-> \fp_eval:n {!0&&(1||0)}--4-> 1

where --i-> is just a step in the process.

Problem: I would like to also include implication, where a->b would be parsed and turned into (!a)||b. The problem is that the replacement in step 1 above is not so simple any longer. I don't know the best way to do this but it seemed like something l3regex might be good at. Thus, I would like a method (whatever might work) of turning expressions of the form

(stuff1)->(stuff(2)) into, (!(stuff1))||(stuff2)

The ability to have these nested to deal with more complicated expressions like

((a)->(b))->(c)

would be amazing but I'm not sure if it's possible. My (probably laughably bad) attempt is below:

\documentclass{article}
\usepackage{xparse}
\usepackage{l3regex}
\ExplSyntaxOn
\regex_new:N \l_tt_impl_regex

% I want to match (stuff1)->(stuff2) and get: (!(stuff1))||(stuff2)
% My thinking, I want to capture the stuff between $$and$$
\regex_set:Nn \l_tt_impl_regex {($$[.]$$)->($$[.]$$)}

\NewDocumentCommand{\imptruth} {m}
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:NnN \l_tt_impl_regex {(!(\1))||(\2)} \l_tmpa_tl
% just to check while mucking around
\tl_show:N \l_tmpa_tl
\fp_eval:n {\l_tmpa_tl}
}

\ExplSyntaxOff
\begin{document}

\imptruth{(1)->(0)}

% is nesting possible??
\imptruth{((0)->(1))->(0)}

\end{document}

-
I'm assuming that, aside from possibly nesting, this is quite an easy problem for someone that knows what they're doing. It would be nice to have someone walk me through the syntax of whatever answer they are able to provide :) – Scott H. Sep 14 '12 at 5:06
Wouldn't it be easier to transform (stuff1)->(stuff2) into -(stuff1)||(stuff2)? – Stephan Lehmke Sep 14 '12 at 9:20
Thanks Stephan, that would be easier :) When looking for a command for logical implication, I overlooked the obvious! I think the essential difficulty remains however, as it's no longer a simple search and replace. – Scott H. Sep 14 '12 at 15:59
Have a look here: stackoverflow.com/questions/2595254/… – egreg Sep 14 '12 at 17:04
@egreg thanks for the link! I'll play around with that first answer and see if I can get something to work. – Scott H. Sep 14 '12 at 17:17

Edit: I guess this is much easier in Lua. After getting some help here with how to implement a Lua matched delimiter pattern, the following code will correctly evaluate nested implications. (Compile with LuaLaTeX)

\documentclass{article}
\usepackage{xparse}

\begingroup
\catcode\%=12\relax
\gdef\patmatch{"(%b())->(%b())","!%1||%2"}
\endgroup

\def\setimpaux#1{%
\directlua{
local s, _ = string.gsub("\luatexluaescapestring{#1}",\patmatch)
tex.sprint(s)
}
}
\ExplSyntaxOn
\cs_new:Npn \set_imp:n #1
{
\tl_set:Nn \l_tmpa_tl {#1}
\tl_if_in:NnT \l_tmpa_tl {->}
{
\tl_set:Nx \l_tmpa_tl {\setimpaux{\l_tmpa_tl}}
\exp_args:NV \set_imp:n \l_tmpa_tl
}

}

\NewDocumentCommand {\evalimplication} {m}
{
\set_imp:n {#1}
\fp_eval:n \l_tmpa_tl
}

\ExplSyntaxOff

\begin{document}

\evalimplication{(0)->(0)}\par
\evalimplication{(0)->(1)}\par
\evalimplication{(1)->(0)}\par
\evalimplication{(1)->(1)}\par
\evalimplication{(0)->((1)->(1))}\par
\evalimplication{((1)->(0))->(1)}

\end{document}


Here are a couple of variations that work for simple expressions, but both break for nested implication (thanks @egreg, the link helped me get to this point). The recursion remains unsolved, however, so I may have to ask a new question for that. If anyone was working on an answer for me, feel free to post it here (or in the new question if/when it appears).

\documentclass{article}
\usepackage{xparse}
\usepackage{l3regex}
\ExplSyntaxOn

% matches lazily, until the next closing parenthesis is found.
\regex_set:Nn \l_tmpa_regex {$$(.+?)$$-\>$$(.+?)$$}
% matches greedily until the last closing parenthesis is found.
\regex_set:Nn \l_tmpb_regex{$$(.+)$$-\>$$(.+)$$}

\NewDocumentCommand{\imptrutha} {m}
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:NnN \l_tmpa_regex {!(\1)||(\2)} \l_tmpa_tl
\tl_show:N \l_tmpa_tl
\fp_eval:n {\l_tmpa_tl}
}
\NewDocumentCommand{\imptruthb} {m}
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:NnN \l_tmpb_regex {!(\1)||(\2)} \l_tmpa_tl
\tl_show:N \l_tmpa_tl
\fp_eval:n {\l_tmpa_tl}
}

\ExplSyntaxOff
\begin{document}

\imptrutha{(0)->(0)}\par
\imptrutha{(0)->(1)}\par
\imptrutha{(1)->(0)}\par
\imptrutha{(1)->(1)}\par\medskip

\imptruthb{(0)->(0)}\par
\imptruthb{(0)->(1)}\par
\imptruthb{(1)->(0)}\par
\imptruthb{(1)->(1)}\par

\end{document}
`
-