我正在写一些关于逻辑和形式语言的笔记,我想提供一些视觉提示来区分形式语言中的符号(例如谓词和逻辑符号)和元语言中的符号。
例如:
其中命题p
、括号和蕴涵箭头都是形式语言的一部分;而F1更像是一个占位符(在元语言中),您可以在其中插入语言中的任何公式。
现在,我可以用下面的代码实现这个效果:
\documentclass{article}
\usepackage{xcolor}
\definecolor{string}{Hsb}{330,0.8,1}
\definecolor{meta-string}{Hsb}{330,0.8,0.6}
\newcommand\lthen{\rightarrow}
\begin{document}
$\textcolor{string}{\mathsf{p} \lthen (\textcolor{meta-string}{F_1} \lthen \mathsf{p})}$
\end{document}
但是,当然,每次都写这些代码很快就会变得乏味,所以我需要写一些宏。这就是我努力寻找“最佳”抽象和更方便的界面来简化代码输入的地方。
一种可能性是定义一些宏,以便我可以输入类似以下内容的内容:
\formal{\symb{p} \lthen (\meta{F_1} \lthen \symb{p})}
这很容易实现,但我仍然认为输入太多了,因为我必须为字符串中的每个符号明确分配一个“类型/类”。
另一种可能性是定义一些宏,以便我可以输入类似的内容:
\formal{p \lthen (\meta{F_1} \lthen p)}
以获得所需的效果。从语义上讲,这也感觉非常正确,但我不知道如何实现它。(特别是如果我对整个公式进行\formal
选择,我不知道如何将其“重置”为正常的数学字体,因为它也将格式应用于下标 1,所以不起作用。)\mathsf
\meta
\mathit
最后,理想的做法是设置成可以\formal
自动确定每个符号的正确字体和颜色,这样我就可以输入
\formal{p \lthen (F_1 \lthen p)}
并得到所需的结果。例如,它可以假设小写字母是语言中的符号,而大写字母是元语言中的符号。或者我可能只需要明确指定哪些符号属于哪种类型以及文档的开头,无论哪种方式都很棒。
所以我的问题是,如何实现这些接口之一?或者还有其他我还没有想到的可能更容易实现的选项?
答案1
它可能不是官方界面,但你可以重置为正常字体模式fam=-1
\documentclass{article}
\usepackage{xcolor}
\definecolor{string}{Hsb}{330,0.8,1}
\definecolor{meta-string}{Hsb}{330,0.8,0.6}
\def\formal#1{\mathsf{\color{string}#1}}
\def\meta#1{\begingroup\fam-1 \color{meta-string}#1\endgroup}
\newcommand\lthen{\rightarrow}
\begin{document}
$\textcolor{string}{\mathsf{p} \lthen (\textcolor{meta-string}{F_1} \lthen \mathsf{p})}$
$\formal{p \lthen (\meta{F_1} \lthen p)}$
\end{document}
答案2
这是你上一个想法的一个相当缓慢的实现(但并不至于变得非常明显):
\documentclass{article}
\usepackage{amsmath,sansmath,xcolor}
\definecolor{string}{Hsb}{330,0.8,1}
\definecolor{meta-string}{Hsb}{330,0.8,0.6}
\newcommand\lthen{\rightarrow}
\makeatletter
\def\change@code@lc#1\relax{%
\mathcode#1=\string"8000
\begingroup\lccode`~=#1
\lowercase{\endgroup\def~}{\text{\normalfont\sffamily\char#1}}%
}
\def\change@code@uc#1\relax{%
\mathcode#1=\string"8000
\begingroup\lccode`~=#1
\lowercase{\endgroup\def~}{%
\text{\normalfont\sffamily\slshape\color{meta-string}\char#1}%
\@ifnextchar_\@uc@subscript{}}%
}
\def\@uc@subscript_#1{_\text{\color{meta-string}$#1$}}
\protected\def\formal{%
\hbox\bgroup
\count@=\numexpr`a-1\relax
\loop\ifnum`z>\count@
\advance\count@\@ne
\expandafter\change@code@lc\number\count@\relax
\repeat
\count@=\numexpr`A-1\relax
\loop\ifnum`Z>\count@
\advance\count@\@ne
\expandafter\change@code@uc\number\count@\relax
\repeat
\@formal
}
\def\@formal#1{\sansmath\color{string}$#1$\egroup}
\makeatother
\begin{document}
\formal{p \lthen (F_1 \lthen p)}
\begin{align}
&\formal{A\lthen b}\\
&\formal{C\lthen D}
\end{align}
\end{document}
只是align
为了表明它在对齐中也起作用(在有限的范围内):对齐的参数\formal
不能包含。&
答案3
关于你的最后一个想法:
对于某些符号/字母使用另一种字体并不困难。例如,对于 p:
\documentclass{article}
\usepackage{xcolor}
\newcommand\lthen{\rightarrow}
\DeclareSymbolFont{formalletters}{OT1}{cmss}{m}{n}
\DeclareMathSymbol{p}\mathalpha{formalletters}{"70}
\begin{document}
$p \lthen (F_1 \lthen p)$
\end{document}
但在这种情况下添加颜色很困难。
使用 xelatex/lualatex 会更容易,因为您可以直接向字体添加颜色:
\documentclass{article}
\usepackage{xcolor}
\usepackage{unicode-math}
\setmathfont[Color=00FF00]{lmodern-math.otf}
\ExplSyntaxOn
%\bool_set_true:N \g_um_uplatin_bool %for upright p
\ExplSyntaxOff
\setmathfont[range={"61-"7A, %a-z
"02192, %\rightarrow
"00028-"00029% parentesis
},
Color=FF0000]{lmodern-math.otf}
\newcommand\lthen{\rightarrow}
\begin{document}
$p \lthen (F_1 \lthen p)$
\end{document}
(lm 现代数学字体的名称可能因您的系统而异)。如果您除了“正式数学”之外还需要普通数学,您可以(可能我没有测试)\mathversion
为“正式数学”设置一个。