initial commit
This commit is contained in:
39
projects/task3/alpha_equiv.c
Executable file
39
projects/task3/alpha_equiv.c
Executable file
@ -0,0 +1,39 @@
|
||||
#include "ast.h"
|
||||
|
||||
bool alpha_equiv(term *t1, term *t2)
|
||||
{
|
||||
if (t1 == (void*) 0 || t2 == (void*) 0)
|
||||
return false;
|
||||
if (t1->type != t2->type)
|
||||
return false;
|
||||
switch (t1->type){
|
||||
case Var: {
|
||||
return strcmp(t1->content.Var, t2->content.Var) == 0;
|
||||
}
|
||||
case Const: {
|
||||
if (t1->content.Const.type != t2->content.Const.type)
|
||||
return false;
|
||||
if (t1->content.Const.type == Num){
|
||||
return t1->content.Const.content == t2->content.Const.content;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Apply: {
|
||||
return alpha_equiv(t1->content.Apply.left, t2->content.Apply.left) &&
|
||||
alpha_equiv(t1->content.Apply.right, t2->content.Apply.right);
|
||||
}
|
||||
case Quant: {
|
||||
if (t1->content.Quant.type != t2->content.Quant.type)
|
||||
return false;
|
||||
if (strcmp(t1->content.Quant.var, t2->content.Quant.var) == 0){
|
||||
return alpha_equiv(t1->content.Quant.body, t2->content.Quant.body);
|
||||
}
|
||||
else{
|
||||
term *t21 = subst_var(t1->content.Quant.var, t2->content.Quant.var, copy_term(t2->content.Quant.body));
|
||||
bool result = alpha_equiv(t1->content.Quant.body, t21);
|
||||
free_term(t21);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
projects/task3/ast.h
Executable file
120
projects/task3/ast.h
Executable file
@ -0,0 +1,120 @@
|
||||
typedef enum {false, true} bool;
|
||||
|
||||
enum const_type
|
||||
{
|
||||
Num = 0,
|
||||
// oper
|
||||
Add,
|
||||
Mul,
|
||||
// pred
|
||||
Eq,
|
||||
Le,
|
||||
// connect
|
||||
And,
|
||||
Or,
|
||||
Impl
|
||||
};
|
||||
typedef enum const_type const_type;
|
||||
|
||||
enum quant_type
|
||||
{
|
||||
Forall,
|
||||
Exists
|
||||
};
|
||||
typedef enum quant_type quant_type;
|
||||
|
||||
enum term_type
|
||||
{
|
||||
Var,
|
||||
Const,
|
||||
Apply,
|
||||
Quant
|
||||
};
|
||||
typedef enum term_type term_type;
|
||||
|
||||
struct term
|
||||
{
|
||||
term_type type;
|
||||
union {
|
||||
char *Var;
|
||||
struct
|
||||
{
|
||||
const_type type;
|
||||
int content;
|
||||
} Const;
|
||||
struct
|
||||
{
|
||||
struct term *left;
|
||||
struct term *right;
|
||||
} Apply;
|
||||
struct
|
||||
{
|
||||
quant_type type;
|
||||
char *var;
|
||||
struct term *body;
|
||||
} Quant;
|
||||
} content;
|
||||
};
|
||||
typedef struct term term;
|
||||
|
||||
struct term_list
|
||||
{
|
||||
term *element;
|
||||
struct term_list *next;
|
||||
};
|
||||
typedef struct term_list term_list;
|
||||
|
||||
typedef struct var_sub
|
||||
{
|
||||
char *var;
|
||||
term *sub_term;
|
||||
} var_sub;
|
||||
|
||||
typedef struct var_sub_list
|
||||
{
|
||||
var_sub *cur;
|
||||
struct var_sub_list *next;
|
||||
} var_sub_list;
|
||||
|
||||
typedef enum {bool_res, termlist} res_type;
|
||||
typedef struct{
|
||||
res_type type;
|
||||
union{
|
||||
bool ans;
|
||||
term_list* list;
|
||||
} d;
|
||||
} solve_res;
|
||||
|
||||
typedef struct{
|
||||
term *assum;
|
||||
term *concl;
|
||||
} ImplyProp;
|
||||
|
||||
/* BEGIN Given Functions */
|
||||
|
||||
// malloc 函数,内存均初始为全0
|
||||
term_list *malloc_term_list();
|
||||
solve_res *malloc_solve_res();
|
||||
|
||||
// 构造函数
|
||||
ImplyProp *createImplyProp(term *t1, term *t2);
|
||||
|
||||
// 深拷贝函数
|
||||
term *copy_term(term *t);
|
||||
term_list *copy_term_list(term_list *list);
|
||||
|
||||
// free 函数
|
||||
void free_str(char *s);
|
||||
void free_imply_prop(ImplyProp *p);
|
||||
void free_term(term *t);
|
||||
void free_term_list(term_list *list);
|
||||
|
||||
// string 相关函数
|
||||
char *strdup(const char *s);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
|
||||
/* END Given Functions */
|
||||
|
||||
term *subst_var(char *den, char *src, term *t);
|
||||
term* subst_term(term* den, char* src, term* t);
|
||||
bool alpha_equiv(term *t1, term *t2);
|
65
projects/task3/subst.c
Executable file
65
projects/task3/subst.c
Executable file
@ -0,0 +1,65 @@
|
||||
#include "ast.h"
|
||||
|
||||
term *subst_var(char *den, char *src, term *t)
|
||||
{
|
||||
switch (t->type)
|
||||
{
|
||||
case Var: {
|
||||
if (!strcmp(t->content.Var, src))
|
||||
{
|
||||
free_str(t->content.Var);
|
||||
t->content.Var = strdup(den);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Const:{
|
||||
break;
|
||||
}
|
||||
case Apply: {
|
||||
t->content.Apply.left = subst_var(den, src, t->content.Apply.left);
|
||||
t->content.Apply.right = subst_var(den, src, t->content.Apply.right);
|
||||
break;
|
||||
}
|
||||
case Quant: {
|
||||
if (strcmp(t->content.Quant.var, src))
|
||||
{
|
||||
t->content.Quant.body = subst_var(den, src, t->content.Quant.body);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
term* subst_term(term* den, char* src, term* t){
|
||||
switch(t->type){
|
||||
case Var:{
|
||||
if(!strcmp(t->content.Var, src)){
|
||||
free_term(t);
|
||||
t = copy_term(den);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Const:{
|
||||
break;
|
||||
}
|
||||
case Apply:{
|
||||
t->content.Apply.left = subst_term(den, src, t->content.Apply.left);
|
||||
t->content.Apply.right = subst_term(den, src, t->content.Apply.right);
|
||||
break;
|
||||
}
|
||||
case Quant:{
|
||||
if(strcmp(t->content.Quant.var,src)){
|
||||
t->content.Quant.body = subst_term(den, src, t->content.Quant.body);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
67
projects/task3/thm_apply.c
Executable file
67
projects/task3/thm_apply.c
Executable file
@ -0,0 +1,67 @@
|
||||
#include "ast.h"
|
||||
|
||||
term* sub_thm(term* thm, var_sub_list* list){
|
||||
if(list == (void*) 0) return copy_term(thm);
|
||||
if(thm->type == Quant){
|
||||
term* den = list->cur->sub_term;
|
||||
return sub_thm(subst_term(den, list->cur->var, thm->content.Quant.body), list->next);
|
||||
}
|
||||
else return (void*) 0;
|
||||
}
|
||||
|
||||
// apply (apply (impl) h1) (h2)
|
||||
//不是imply形式时返回(void*) 0
|
||||
ImplyProp *separate_imply(term *t)
|
||||
{
|
||||
if (t->type != Apply || t->content.Apply.left->type != Apply ||
|
||||
t->content.Apply.left->content.Apply.left->type != Const ||
|
||||
t->content.Apply.left->content.Apply.left->content.Const.type != Impl)
|
||||
return (void*) 0;
|
||||
else
|
||||
return createImplyProp(t->content.Apply.left->content.Apply.right, t->content.Apply.right);
|
||||
}
|
||||
|
||||
//根据定理形式,匹配结论,得出要检验的前提
|
||||
term_list* check_list_gen(term* thm, term* target) {
|
||||
if (thm == (void*) 0 || target == (void*) 0) {
|
||||
return (void*) 0;
|
||||
}
|
||||
term_list* check_list = (void*) 0;
|
||||
term_list** tail_ptr = &check_list;
|
||||
while (thm != (void*) 0 && !alpha_equiv(thm, target)) {
|
||||
ImplyProp* p = separate_imply(thm);
|
||||
if (p == (void*) 0) {
|
||||
free_term_list(check_list);
|
||||
return (void*) 0;
|
||||
}
|
||||
// 添加新节点到链表
|
||||
term_list* new_node = malloc_term_list();
|
||||
new_node->element = p->assum; // 转移所有权
|
||||
new_node->next = (void*) 0;
|
||||
|
||||
*tail_ptr = new_node;
|
||||
tail_ptr = &(new_node->next);
|
||||
thm = p->concl;
|
||||
free_imply_prop(p); // 释放ImplyProp结构体(不释放其成员)
|
||||
}
|
||||
return check_list;
|
||||
}
|
||||
|
||||
|
||||
solve_res* thm_apply(term* thm, var_sub_list* list, term* goal){
|
||||
term* thm_ins = sub_thm(thm, list);
|
||||
solve_res* res = malloc_solve_res();
|
||||
if(thm_ins == (void*) 0) {
|
||||
res->type = bool_res;
|
||||
res->d.ans = false;
|
||||
}
|
||||
else if(alpha_equiv(thm_ins, goal)){
|
||||
res->type = bool_res;
|
||||
res->d.ans = true;
|
||||
}
|
||||
else{
|
||||
res->type = termlist;
|
||||
res->d.list = check_list_gen(thm_ins, goal);
|
||||
}
|
||||
return res;
|
||||
}
|
Reference in New Issue
Block a user