高等数理逻辑大作业
这明明就是一个披着数理逻辑外衣的编译器 :)
以 C 或 javascript 实现命题逻辑公式语法检查及公式求值.
一、要求
名词声明
-
命题变元
- 字母及数字构成的字符串且首字符是字母
- 字符串长度不超过 10
-
第一类逻辑联结词:
- 0,1,¬,∧,∨,→,⊕,↔
-
第二类逻辑联结词(新定义逻辑联结词):
- 字母及数字构成的字符串且首字符是字母
- 给出逻辑联结词的元数及真值表的最后一列
- 一共不超过 10 个新定义逻辑联结词
- 新定义逻辑联结词元数不超过 10
任务
第一部分:
- [ ]
对于不是命题逻辑公式的字符串,至少指明一处语法错误 - [x] 进行永真及永假判断,对于不是永真及永假的命题逻辑公式,给出使得该公式成立的所有真值赋值
第二部分
- [x] 对于给定的逻辑联结词的有限集合,判断它是否为完全的
- [ ]
写出由不超出二元的逻辑联结词构成的所有的逻辑联结词的最小完全集
二、测试用例:
测试 | 结果 |
---|---|
(p1⊕r3)∧(q1⊕p3)∧(r1⊕p2)∧¬(p1∧q1)∧¬(p1∧r1)∧ ¬(q1∧r1)∧¬(p3∧r3)∧¬(p1∧p2)∧¬(p1∧p3)∧¬(p2∧p3)∧¬(r1∧r3) |
仅取011001成立 |
(p)⊕(q↔r) | 10010110 |
f((p),g(q, r)) # f 2 0110 g 2 1001 | 10010110 不完全 |
(0∧0∨0∨0→0)⊕0↔0 | 永假 |
((q ⊕ r) ⊕s)↔(q ⊕ (r ⊕s)) | 永真 |
f(p, f(q, r))↔f(f(p,q),r) #f 2 1001 | 永真,不完全 |
F(0,1,F(0,0,ff(0)))→0 #F 3 00000011 ff 1 01 | 永真,不完全 |
F(p, q, F(p, p, ff(p)))→p #F 3 00000011 ff 1 01 | 永真,不完全 |
F(p, q, F(p, p, g(q,f(p))))→p #F 3 00000011 f 1 01 g 2 0011 | 永真,不完全 |
F(p, q, F(p, p, g(q,f(p))))→p #F 3 10000011 f 1 10 g 2 1100 | 0111,完全 |
#f 2 0110 g 1 10 | 不完全 |
p→q↔f(f(q,f(q,p,p),p),p,p) #f 3 10010010 | 永真,完全 |
¬p↔f(p,p,p) #f 3 10010010 | 永真,完全 |
#f 2 0110 g 2 0111 h 2 0001 | 不完全 |
#f 2 0001 g 2 1001 h 2 0110 | 完全 |
#f 2 0111 g 2 1001 h 1 00 | 完全 |
#f 2 0111 g 2 0001 h 2 1101 i 2 1001 | 不完全 |
p→q↔f(f(q,q,p),f(p,p,p),p) #f 3 11000010 | 永真,完全 |
¬p↔f(p,p,p) #f 3 11000010 | 永真,完全 |
#f 2 0111 g 2 0001 h 2 1101 k 2 1001 | 不完全 |
p→q↔g(h(q,p),q) #f 2 0110 g 2 0111 h 2 1001 | 永真,完全 |
¬p↔f(h(p,p),p) #f 2 0110 g 2 0111 h 2 1001 | 永真,完全 |
#f 2 0110 | 不完全 |
p→q↔f(h(),f(p,q)) #f 2 0010 h 0 1 | 永真,完全 |
¬p↔f(h(),p) # f 2 0010 h 0 1 | 永真,完全 |
三、实现
1. 写个文法先
- 因子
¬
+因子
(
+五级项
+)
标识符
+(
+五级项
+ [,五级项
] +)
标识符
+()
标识符
0,1
- 一级项
因子
因子
+∧
+因子
+ [∧
+因子
]
- 二级项
一级项
一级项
+∨
+一级项
+ [∨
+一级项
]
- 三级项
二级项
二级项
+⊕
+二级项
+ [⊕
+二级项
]
- 四级项
三级项
三级项
+→
+三级项
+ [→
+三级项
]
- 五级项
四级项
四级项
+↔
+四级项
+ [↔
+四级项
]
- 表达式
五级项
+ [联结词定义
]联结词定义
- 联结词定义
#
+标识符
+因子个数
+真值表最后一列
+ [标识符
+因子个数
+真值表最后一列
]
2. 跟编译差不多
3. 判断是否完全
一个很有用的链接:数字逻辑中的最小完全集
算法伪码:
初始集合为A = [0101,0011]
con = true;
while con
{
con = false;
for 联结词 in 联结词集合
{
//如果是n元联结词,且当前集合A中有m个元素
//循环次数 k = m^n
for(i = 0;i<k;i++)
{
//根据i选取这n个元素,将i看作是一个n位m进制数,求得i在m进制下的每一位,即对应所有可选情况
//使用联结词计算,得到新的结果
if 是新结果
加入集合A
con = true
}
}
}