c++写一个程序,给定一个谓词公式,将其转化为子句集,保证等值符至多出现一次,或者不出现,谓词符号和个体词符号不与上述连接词冲突,.利用归结原理对子句集中的子句进行归结
时间: 2023-10-03 07:03:55 浏览: 287
以下是一个简单的C++程序,可以将给定的谓词公式转化为子句集,并使用归结原理对子句集中的子句进行归结。请注意,此程序仅支持包含逻辑连接词“AND”和“OR”的谓词公式。
```c++
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
// 定义谓词公式结构体
struct Predicate {
string symbol; // 谓词符号
vector<string> args; // 个体词符号
bool negated; // 是否是否定
};
// 将字符串按照指定分隔符分割成vector
vector<string> split(const string& s, char delimiter) {
vector<string> tokens;
string token;
istringstream tokenStream(s);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
// 解析谓词公式
Predicate parsePredicate(string pred) {
Predicate p;
if (pred[0] == '~') { // 如果是否定式
p.negated = true;
pred = pred.substr(1); // 去掉负号
} else {
p.negated = false;
}
int left_paren = pred.find("(");
int right_paren = pred.find(")");
p.symbol = pred.substr(0, left_paren); // 提取谓词符号
string args_str = pred.substr(left_paren+1, right_paren-left_paren-1); // 提取个体词符号
p.args = split(args_str, ',');
return p;
}
// 将谓词公式转化为子句
string predToClause(const Predicate& p) {
string clause = "";
if (p.negated) {
clause += "~"; // 加上否定符号
}
clause += p.symbol + "(";
for (int i=0; i<p.args.size(); i++) {
clause += p.args[i];
if (i != p.args.size()-1) {
clause += ",";
}
}
clause += ")";
return clause;
}
// 将谓词公式集合转化为子句集合
vector<string> predsToClauses(const vector<Predicate>& preds) {
vector<string> clauses;
for (auto p : preds) {
clauses.push_back(predToClause(p));
}
return clauses;
}
// 将子句按照长度排序
bool compareClauseLen(string c1, string c2) {
return c1.length() < c2.length();
}
// 判断两个谓词公式是否可以进行归结
bool canResolve(const Predicate& p1, const Predicate& p2) {
if (p1.negated == p2.negated) { // 如果两个谓词符号的否定性相同,则无法进行归结
return false;
}
if (p1.symbol != p2.symbol) { // 如果两个谓词符号不相同,则无法进行归结
return false;
}
int num_diff_args = 0; // 统计不同的个体词符号数量
for (auto arg1 : p1.args) {
for (auto arg2 : p2.args) {
if (arg1 == arg2) {
num_diff_args++;
break;
}
}
}
return num_diff_args == p1.args.size()-1; // 如果只有一个个体词符号不同,则可以进行归结
}
// 归结两个子句,返回新的子句
string resolveClauses(const string& c1, const string& c2) {
vector<Predicate> preds1, preds2;
vector<Predicate> resolved_preds;
vector<string> resolved_args;
vector<string> resolved_clauses;
// 解析子句中的谓词公式
string c1_pred_str = c1.substr(0, c1.find("("));
string c2_pred_str = c2.substr(0, c2.find("("));
preds1.push_back(parsePredicate(c1));
preds2.push_back(parsePredicate(c2));
for (int i=0; i<preds1[0].args.size(); i++) {
if (preds1[0].args[i] != preds2[0].args[i]) {
resolved_args.push_back(preds1[0].args[i]);
}
}
for (int i=0; i<preds1.size(); i++) {
for (int j=0; j<preds2.size(); j++) {
if (canResolve(preds1[i], preds2[j])) {
Predicate resolved_pred;
resolved_pred.symbol = preds1[i].symbol;
resolved_pred.negated = false;
for (int k=0; k<preds1[i].args.size(); k++) {
if (preds1[i].args[k] != preds2[j].args[k]) {
resolved_pred.args.push_back(resolved_args[0]);
} else {
resolved_pred.args.push_back(preds1[i].args[k]);
}
}
resolved_preds.push_back(resolved_pred);
}
}
}
// 将新生成的谓词公式转化为子句
for (auto p : resolved_preds) {
resolved_clauses.push_back(predToClause(p));
}
// 将两个子句中不包含在新生成的子句中的部分合并起来
string new_clause = "";
for (auto arg : resolved_args) {
new_clause += arg + ",";
}
new_clause.pop_back();
new_clause = c1_pred_str + "(" + new_clause + ") OR " + c2_pred_str + "(" + new_clause + ")";
for (auto c : resolved_clauses) {
new_clause = new_clause + " OR " + c;
}
return new_clause;
}
// 归结子句集合中的所有子句
vector<string> resolveAll(const vector<string>& clauses) {
vector<string> resolved_clauses = clauses;
bool has_resolved = true;
while (has_resolved) {
has_resolved = false;
sort(resolved_clauses.begin(), resolved_clauses.end(), compareClauseLen); // 按照长度排序,使得长度小的子句先进行归结
for (int i=0; i<resolved_clauses.size(); i++) {
for (int j=i+1; j<resolved_clauses.size(); j++) {
if (canResolve(parsePredicate(resolved_clauses[i]), parsePredicate(resolved_clauses[j]))) { // 如果可以进行归结
string new_clause = resolveClauses(resolved_clauses[i], resolved_clauses[j]); // 归结两个子句
if (new_clause != "") { // 如果生成了新子句
resolved_clauses.push_back(new_clause); // 将新子句加入子句集合
has_resolved = true; // 标记已经进行过归结
break;
}
}
}
if (has_resolved) {
break;
}
}
}
return resolved_clauses;
}
int main() {
string input;
cout << "请输入谓词公式:" << endl;
getline(cin, input);
// 将谓词公式按照“AND”分割成子公式
vector<string> and_preds = split(input, '&');
// 将子公式按照“OR”分割成谓词公式
vector<Predicate> preds;
for (auto ap : and_preds) {
vector<string> or_preds = split(ap, '|');
for (auto op : or_preds) {
preds.push_back(parsePredicate(op));
}
}
// 将谓词公式转化为子句集合
vector<string> clauses = predsToClauses(preds);
// 归结子句集合中的所有子句
vector<string> resolved_clauses = resolveAll(clauses);
// 输出归结结果
cout << "子句集合为:" << endl;
for (auto c : clauses) {
cout << c << endl;
}
cout << "==================================" << endl;
if (resolved_clauses.size() == 0) {
cout << "无法进行归结" << endl;
} else {
cout << "归结结果为:" << endl;
for (auto rc : resolved_clauses) {
cout << rc << endl;
}
}
return 0;
}
```
需要注意的是,此程序仅支持包含逻辑连接词“AND”和“OR”的谓词公式。如果需要支持更复杂的公式,请根据需求进行扩展。
阅读全文