1003 Reasoning(大模拟)

原题链接

translation

现有一个推理系统,有如下符号组成:

  • 圆括号:()
  • 逻辑连词:¬
  • 全称量词:
  • 变量:uz
  • 常量:ae
  • 函数:fh
  • 谓词:PT

这个推理系统还包括项(term)、公式(formula)、自由出现(free occurrence)和替换(replacement)等概念。基于这些概念,我们可以定义某个项 t 是否可以毫无冲突地替换某个变量 x。这是推理的基础之一,你想先解决这个问题。

项(term)的定义如下:

  • 所有的变量 v 是一个项
  • 所有的常量 c 是一个项
  • 如果 t1,t2,,tn 是一些项,f 是一个函数,则 ft1,t2,,tn 是一个项

公式(formula)的定义如下:

  • 如果 t1,t2,,tn 是一些项,P 是一个谓词,则 Pt1,t2,,tn 是一个公式,而且这种公式被称为原子公式(atomic formula)
  • 如果 φψ 都是公式,则 (¬φ)(φψ) 都是公式
  • 如果 φ 是公式,v 是变量,则 vφ 是公式

x 可以在 φ 中自由出现(free occurrence)的定义如下:

  • 如果 φ 是原子公式,x 可以在 φ 中自由出现当且仅当在 φ 中有 x(可以理解为字符 x 在字符串 φ 中出现)
  • 如果 φ(¬ψ)x 可以在 φ 中自由出现当且仅当 x 可以在 ψ 中自由出现
  • 如果 φ(ψγ)x 可以在 φ 中自由出现当且仅当 x 可以在 ψ 中自由出现或在 γ 中自由出现
  • 如果 φvψx 可以在 φ 中自由出现当且仅当 x 可以在 ψ 中自由出现且 xv

对于所有公式 φ,变量 x,项 t,替换(replacement)φtx 的定义如下:

  • 如果 φ 是原子公式,那么 φtx 是通过简单地将每个字符 x 替换为字符串 t 形成的表达式
  • 如果 φ(¬ψ),那么 (¬ψ)tx=(¬ψtx)
  • 如果 φ(ψγ),那么 (ψγ)tx=(ψtxγtx)
  • 如果 φyψ,那么 (yψ)tx={y(ψtx)if xyyψif x=y

最后,无冲突替换的定义如下:

  • 如果 φ 是原子公式,那么 t 始终可以在 φ 中无冲突替换 x
  • 如果 φ(¬ψ),那么 tφ 中可以无冲突替换 x 当且仅当 tψ 中可以无冲突替换 x
  • 如果 φ(ψγ),那么 tφ 中可以无冲突替换 x 当且仅当 tψγ 中都可以无冲突替换 x
  • 如果 φyψ,那么 tφ 中可以无冲突替换 x 当且仅当:
    • x 不能在 φ 中自由出现,或
    • y 不能在 t 中自由出现,且 tψ 中可以无冲突替换 x

现在,你需要判断项 t 是否可以无冲突替换 x

solution

模拟即可。

在代码实现上,我忽略了所有 ),然后把左括号当做一个有 2 个参数的函数,把 ¬ 当成一个没有参数的函数,最后把所有变量和常量都当成没有参数的函数,这样整个公式中就只有谓语,函数和 ,可以一起实现。

code

#define pb push_back
int T; string s; int m, num[300]; int q; bool v[120][6]; int fa[120];
bool vis[6];
bool IS (char c) {return (c >= 'f' && c <= 'h') || (c >= 'P' && c <= 'T') || (c == '(');}
bool az[120];
void Find (int a, int id) {
	RI i, j; az[id] = 1; int lst = id; for (i = 1; i <= a; ++ i) {
		W (az[id]) ++ id; fa[id] = lst; Find (num[s[id]], id);
	}
}
bool qus[11];
int main () {
	RI i, j; Read (T); W (T --) {
		Mt (fa, -1); Mt (az, 0); Mt (num, 0); Mt (v, 0);
		cin >> s; int n = s.length (); s = " " + s; Read (m);
		for (i = 1; i <= m; ++ i) {char c; int x; Readc (c); Read (x); num[c] = x;} num['('] = 2;
		for (i = 1; i <= n; ++ i) if (s[i] == 'I' || s[i] == ')' || s[i] == 'A' || s[i - 1] == 'A') az[i] = 1;
		for (i = 1; i <= n; ++ i) if (IS (s[i])) {Find (num[s[i]], i); break;}
		bool flag = 0; for (i = 1; i <= n; ++ i) {
			if (s[i] == 'A') {vis[s[i + 1] - 'u'] = 1; ++ i; flag = 1;}
			else if (flag == 1) {for (j = 0; j <= 5; ++ j) v[i][j] |= vis[j]; Mt (vis, 0); flag = 0;} 
		} for (i = 1; i <= n; ++ i) {
			if (fa[i] == -1) continue; for (j = 0; j <= 5; ++ j) v[i][j] |= v[fa[i]][j];
		}
		Read (q); W (q --) {
			string ca; char c; cin >> ca; Readc (c); int len = ca.length (); Mt (qus, 0); 
			for (i = 0; i < len; ++ i) {
				if (ca[i] >= 'a' && ca[i] <= 'e') qus[ca[i] - 'a'] = 1;
				if (ca[i] >= 'u' && ca[i] <= 'z') qus[ca[i] - 'u' + 5] = 1;
			}
			bool YN = 1; for (i = 1; i <= n; ++ i) {
				if (s[i] != c) continue;
				if (fa[i] == -1) continue;
				if (v[i][c - 'u'] == 1) continue;
				for (j = 0; j <= 5; ++ j) {
					if (v[i][j] && qus[j + 5]) {YN = 0; break;}
				}
			}
			putchar (YN ? 'Y' : 'N'); printf ("\n"); if (! YN) continue;
			for (i = 1; i <= n; ++ i) {
				if (s[i] != c) printf ("%c", s[i]);
				else if (v[i][c - 'u'] == 1) printf ("%c", s[i]);
				else if (fa[i] == -1) printf ("%c", s[i]);
				else printf ("%s", ca.c_str ());
			} printf ("\n");
		}
	}
	return 0; 
}
posted @   ClapEcho233  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示