离散数学,自然推理系统,基于假言推理,不能使用消解法的自然推理系统

本文详细介绍了如何实现一个基于假言推理的自然推理系统,包括课本代码解析、优化策略和个性化编程实现。通过实例展示和代码展示,展示了程序的运行逻辑、结果分析以及优化后的特色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

离散数学-假言推理系统

1. 问题描述

自然推理系统(基于假言推理,不能使用消解法的自然推理系统)。 跑通老师的例题占60分。提交word文档:包含源码截图,多组测试数据的运行结果截图。验收时:按助教小老师的要求输入测试数据,正确者给60分。 对老师代码的改进占40分。跟60分部分在同一 个word文档中,为什么改进? ,如何改进? ,改进代码截图。
验收时:给助教小老师讲解为什么,如何改?讲解清楚,, 回答问题正确,给分5-40分。由于每个助教只检查-道题,因此他非常清楚此题已经改进的地方。前3个改进者才有效得分。

2. 课本中的源码

(1) 抄写课本中的代码

  1. 先看着课本把代码全部编写完成,并编译保证代码能正常运行,源码如下

    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <time.h>
    using namespace std;
    
    struct oTm {
    	string gs, gsLast, niyou; // 前件与后件及理由
    	int nLitter, nUsed, isLitter, isCond;
    };
    
    
    void nonoop2(string & aa) {
    	int i = 0, j = 0;
    	int len = aa.length();
    	while(i < len - 2) {
    		// 至少还有2个字符
    		if(((i + 1) < len) && (aa[i] == '!') && (aa[i + 1] == '!')) {
    			j = i;
    			aa = aa.substr(j + 2, len - 2);
    			break;
    		} else {
    			i++;
    		}
    	}
    }
    
    int setNiYou(struct oTm tmrec[], int np, string ny0, int j0, int j1, int nUsed0, int isCond0, int isLitter0) {
    	// 将字符串ny0与j0赋到推理意见中
    	string stmpj0, stmpj1;
    //	int nLen1 = 0, j = 0, nLenj0 = 0, nLenj1 = 0;
    //	nLen1 = ny0.length();
    	stmpj0 = to_string(j0 + 1);
    //	nLenj0 = stmpj0.length();
    	stmpj1 = to_string(j1 + 1);
    //	nLenj1 = stmpj1.length();
    	if(j0 == -1) {
    		// 原始前提
    		tmrec[np].niyou = ny0;
    	} else if(j1 == -1) {
    		//  由前一步所得结论
    		tmrec[np].niyou = "(" + stmpj0 + ")" + ny0;
    	} else {
    		// 由前二步推理所得
    		tmrec[np].niyou = "(" + stmpj0 + ")" + "(" + stmpj1 + ")" + ny0;
    	}
    	tmrec[np].nUsed = nUsed0; // 附加前提从未使用过
    	tmrec[np].isCond = isCond0; // 是条件式
    	tmrec[np].isLitter = isLitter0; // 是文字
    }
    
    int inputPrimary(struct oTm gs0[]) {
    	struct oTm tmp;
    	string pstate;
    	string ny0 = "前提条件";
    	string ny1 = "原命题的逆否命题";
    	string ny2 = "双条件导出的条件式";
    	string ny3 = "析取式转换为条件式";
    	int i = 0, j = 0, nLen = 0, k = 0;
    	int i0 = 0; // 原始条件
    	printf("输完一个前提条件请按回车,不输直接按回车则结束\n 析 +, 合*, 条-,双=,否定!\n");
    	while(1) {
    		getline(cin, pstate);
    		nLen = pstate.length();
    		if(nLen == 0) {
    			break;
    		}
    		// 设置nUsed, isLitter, isCond, nLitter的值
    		// 判断是否为文字
    		if(nLen == 1) {
    			// 标注单个文字
    			gs0[i].nLitter = nLen;
    			gs0[i].gs = pstate; // 前件
    			gs0[i].gsLast = ""; // 后件
    			setNiYou(gs0, i, ny0, -1, -1, 0, 0, 1);
    			// 前提类型, 无, 无, 未使用, 不是条件式, 是文字
    		} else if((nLen == 2) && (pstate[0] == '!')) {
    			// 标注!p
    			gs0[i].nLitter = nLen;
    			gs0[i].gs = pstate; // 前件
    			gs0[i].gsLast = ""; // 后件
    			setNiYou(gs0, i, ny0, -1, -1, 0, 0, 1);
    		} else {
    			for(j = 0; j < nLen; j++) {
    				if(pstate[j] == '-') {
    					// 标注条件式 p - q
    					gs0[i].nLitter = pstate.length();
    					gs0[i].gs = pstate.substr(0, j); // 复制前件
    					gs0[i].gsLast = pstate.substr(j + 1, nLen); // 复制后件
    					setNiYou(gs0, i, ny0, -1, -1, 0, 1, 0); // 前提,是条件,不是文字
    					// 产生逆否条件 !q-!p
    					i++;
    					gs0[i].nLitter = gs0[i - 1].nLitter;
    					gs0[i].gsLast = "!" + pstate.substr(0, j);
    					nonoop2(gs0[i].gsLast);
    
    					// 复制前件
    					gs0[i].gs = "!" + pstate.substr(j + 1, nLen);
    					nonoop2(gs0[i].gs);
    					setNiYou(gs0, i, ny1, i-1, -1, 0, 1, 0); // 前提,是条件,不是文字
    					break;
    				} else if(pstate[j] == '=') {
    					// 标注双条件式
    					// 先保存双条件
    					gs0[i].nLitter = pstate.length();
    					// 保存全部
    					gs0[i].gs = pstate;
    					gs0[i].gsLast = "";
    					setNiYou(gs0, i, ny0, -1, -1, 0, 0, 0); // 前提,不是条件,不是文字
    					// p-q
    					i++;
    					// 复制前件
    					gs0[i].nLitter = pstate.length();
    					gs0[i].gs = pstate.substr(0, j);
    					// 复制后件
    					gs0[i].gsLast = pstate.substr(j + 1, nLen);
    					setNiYou(gs0, i, ny2, i-1, -1, 0, 1, 0); // 前提,是条件,不是文字
    					
    					// 产生逆否条件 !q-!p
    					i++;
    					gs0[i].nLitter = gs0[i - 1].nLitter;
    					gs0[i].gsLast = "!" + pstate.substr(0, j);
    					nonoop2(gs0[i].gsLast);
    
    					// 复制前件
    					gs0[i].gs = "!" + pstate.substr