我对正则表达式的用法和语法非常不熟悉,所以下面的问题让我很头疼。
背景:
我正在采用逻辑表达式,对其进行解析,进行一些替换,然后使用对其进行评估\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}