正则表达式的逻辑含义?

正则表达式的逻辑含义?

我对正则表达式的用法和语法非常不熟悉,所以下面的问题让我很头疼。

背景: 我正在采用逻辑表达式,对其进行解析,进行一些替换,然后使用对其进行评估\fp_eval:n。例如,

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

--i->只是流程中的一个步骤。

问题:我还想包括蕴涵,其中a->b将被解析并转换为(!a)||b。问题是上面步骤 1 中的替换不再那么简单了。我不知道最好的方法是什么,但似乎有些方法l3regex可能很好。因此,我想要一种方法(无论什么可能有效)来将形式表达式转换为

(stuff1)->(stuff(2)) 进入, (!(stuff1))||(stuff2)

嵌套这些函数可以处理更复杂的表达式,例如

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

会很棒,但我不确定这是否可行。我的(可能糟糕得可笑的)尝试如下:

\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}

答案1

编辑: 我想这在 Lua 中会容易得多。在获得一些帮助后这里如何实现 Lua 匹配的分隔符模式,以下代码将正确评估嵌套蕴涵。(使用 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}

这里有几个适用于简单表达式的变体,但都无法用于嵌套蕴涵(感谢@egreg,这个链接帮助我找到了这一点)。然而,递归仍然未解决,所以我可能不得不为此提出一个新问题。如果有人正在为我寻找答案,请随时在此处发布(或者在新问题出现时发布)。

\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}

相关内容