initial commit
This commit is contained in:
31
.gitignore
vendored
Executable file
31
.gitignore
vendored
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
# config file
|
||||||
|
CONFIGURE
|
||||||
|
SUB_CONFIGURE
|
||||||
|
|
||||||
|
# Object files, in general
|
||||||
|
*.glob
|
||||||
|
*.vo
|
||||||
|
*.vo[ks]
|
||||||
|
.*.aux
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.depend
|
||||||
|
|
||||||
|
# Generated by MacOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Coq caches
|
||||||
|
.lia.cache
|
||||||
|
.nia.cache
|
||||||
|
.nra.cache
|
||||||
|
.csdp.cache
|
||||||
|
|
||||||
|
assignments
|
||||||
|
compcert_lib
|
||||||
|
monadlib
|
||||||
|
pv
|
||||||
|
qcp
|
||||||
|
qualifiedcprogramming
|
||||||
|
sets
|
||||||
|
.gitmodules
|
||||||
|
_CoqProject
|
76
Makefile
Executable file
76
Makefile
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
CURRENT_DIR=.
|
||||||
|
SETS_DIR = sets
|
||||||
|
COMPCERT_DIR = compcert_lib
|
||||||
|
PV_DIR = pv
|
||||||
|
COQBIN=
|
||||||
|
|
||||||
|
-include CONFIGURE
|
||||||
|
|
||||||
|
COQC=$(COQBIN)coqc
|
||||||
|
COQDEP=$(COQBIN)coqdep
|
||||||
|
|
||||||
|
PV_FLAG = -R $(PV_DIR) PV -R $(SETS_DIR) SetsClass -R $(COMPCERT_DIR) compcert.lib
|
||||||
|
|
||||||
|
SETS_FLAG = -R $(SETS_DIR) SetsClass
|
||||||
|
|
||||||
|
COMPCERT_FLAG = -R $(COMPCERT_DIR) compcert.lib
|
||||||
|
|
||||||
|
DEP_FLAG = -R $(PV_DIR) PV -R $(SETS_DIR) SetsClass -R $(COMPCERT_DIR) compcert.lib
|
||||||
|
|
||||||
|
SETS_FILE_NAMES = \
|
||||||
|
SetsClass.v SetsDomain.v SetElement.v RelsDomain.v SetElementProperties.v SetProd.v SetsClass_AxiomFree.v SetsDomain_Classic.v
|
||||||
|
|
||||||
|
SETS_FILES=$(SETS_FILE_NAMES:%.v=$(SETS_DIR)/%.v)
|
||||||
|
|
||||||
|
COMPCERT_FILE_NAMES = \
|
||||||
|
Coqlib.v Integers.v Zbits.v
|
||||||
|
|
||||||
|
COMPCERT_FILES=$(COMPCERT_FILE_NAMES:%.v=$(COMPCERT_DIR)/%.v)
|
||||||
|
|
||||||
|
PV_FILE_NAMES = \
|
||||||
|
Intro.v SimpleProofsAndDefs.v InductiveType.v \
|
||||||
|
Syntax.v RecurProp.v ExprIntDenotation.v ExprBoolDenotation.v BuiltInNat.v \
|
||||||
|
Logic.v RelsAsDenotations.v FixedPoint.v \
|
||||||
|
HoareLogic.v Monad.v BuiltInList.v
|
||||||
|
|
||||||
|
PV_FILES=$(PV_FILE_NAMES:%.v=$(PV_DIR)/%.v)
|
||||||
|
|
||||||
|
FILES = $(PV_FILES) \
|
||||||
|
$(SETS_FILES) \
|
||||||
|
$(COMPCERT_FILES)
|
||||||
|
|
||||||
|
$(SETS_FILES:%.v=%.vo): %.vo: %.v
|
||||||
|
@echo COQC $<
|
||||||
|
@$(COQC) $(SETS_FLAG) $<
|
||||||
|
|
||||||
|
$(COMPCERT_FILES:%.v=%.vo): %.vo: %.v
|
||||||
|
@echo COQC $<
|
||||||
|
@$(COQC) $(COMPCERT_FLAG) $<
|
||||||
|
|
||||||
|
$(PV_FILES:%.v=%.vo): %.vo: %.v
|
||||||
|
@echo COQC $(<F)
|
||||||
|
@$(COQC) $(PV_FLAG) $<
|
||||||
|
|
||||||
|
all: $(FILES:%.v=%.vo)
|
||||||
|
|
||||||
|
_CoqProject:
|
||||||
|
@echo $(DEP_FLAG) > _CoqProject
|
||||||
|
|
||||||
|
depend: $(FILES)
|
||||||
|
$(COQDEP) $(DEP_FLAG) $(FILES) > .depend
|
||||||
|
|
||||||
|
.depend: $(FILES)
|
||||||
|
@$(COQDEP) $(DEP_FLAG) $(FILES) > .depend
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f *.glob */*.glob
|
||||||
|
@rm -f *.vo */*.vo
|
||||||
|
@rm -f *.vok */*.vok
|
||||||
|
@rm -f *.vos */*.vos
|
||||||
|
@rm -f .*.aux */.*.aux
|
||||||
|
@rm -f .depend
|
||||||
|
|
||||||
|
.PHONY: clean depend
|
||||||
|
.DEFAULT_GOAL := all
|
||||||
|
|
||||||
|
-include .depend
|
275
projects/task1/mini-gmp.c
Executable file
275
projects/task1/mini-gmp.c
Executable file
@ -0,0 +1,275 @@
|
|||||||
|
#include "mini-gmp.h"
|
||||||
|
|
||||||
|
mp_size_t gmp_abs(mp_size_t x) {
|
||||||
|
return x >= 0 ? x : -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_size_t gmp_max(mp_size_t a, mp_size_t b) {
|
||||||
|
return a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int gmp_cmp(mp_size_t a, mp_size_t b) {
|
||||||
|
return (a > b) - (a < b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPN interface */
|
||||||
|
|
||||||
|
/* 从 低地址向高地址 顺序复制 */
|
||||||
|
void
|
||||||
|
mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
|
||||||
|
{
|
||||||
|
mp_size_t i;
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 大于返回1,小于返回-1,等于返回0 */
|
||||||
|
int
|
||||||
|
mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n)
|
||||||
|
{
|
||||||
|
while (--n >= 0)
|
||||||
|
{
|
||||||
|
if (ap[n] != bp[n])
|
||||||
|
return ap[n] > bp[n] ? 1 : -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*处理位数不同的情况*/
|
||||||
|
static int
|
||||||
|
mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
|
||||||
|
{
|
||||||
|
if (an != bn)
|
||||||
|
return an < bn ? -1 : 1;
|
||||||
|
else
|
||||||
|
return mpn_cmp (ap, bp, an);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*返回非0的位数*/
|
||||||
|
static mp_size_t
|
||||||
|
mpn_normalized_size (mp_srcptr xp, mp_size_t n)
|
||||||
|
{
|
||||||
|
while (n > 0 && xp[n-1] == 0)
|
||||||
|
--n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 多精度数ap 加上单精度数b,返回最后产生的进位 */
|
||||||
|
mp_limb_t
|
||||||
|
mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
|
||||||
|
{
|
||||||
|
mp_size_t i;
|
||||||
|
//assert (n > 0);
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mp_limb_t r = ap[i] + b;
|
||||||
|
/* Carry out */
|
||||||
|
b = (r < b);
|
||||||
|
rp[i] = r;
|
||||||
|
}
|
||||||
|
while (++i < n);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 位数相同的多精度数ap 加上多精度数bp,返回最后产生的进位 */
|
||||||
|
mp_limb_t
|
||||||
|
mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
|
||||||
|
{
|
||||||
|
mp_size_t i;
|
||||||
|
mp_limb_t cy;
|
||||||
|
|
||||||
|
for (i = 0, cy = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
mp_limb_t a, b, r;
|
||||||
|
a = ap[i]; b = bp[i];
|
||||||
|
r = a + cy;
|
||||||
|
cy = (r < cy);
|
||||||
|
r += b;
|
||||||
|
cy += (r < b);
|
||||||
|
rp[i] = r;
|
||||||
|
}
|
||||||
|
return cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*不同位数的多精度数相加,返回最后的进位*/
|
||||||
|
mp_limb_t
|
||||||
|
mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
|
||||||
|
{
|
||||||
|
mp_limb_t cy;
|
||||||
|
//assert (an >= bn);
|
||||||
|
cy = mpn_add_n (rp, ap, bp, bn);
|
||||||
|
if (an > bn)
|
||||||
|
cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy);
|
||||||
|
return cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_limb_t
|
||||||
|
mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
|
||||||
|
{
|
||||||
|
mp_size_t i;
|
||||||
|
//assert (n > 0);
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mp_limb_t a = ap[i];
|
||||||
|
/* Carry out */
|
||||||
|
mp_limb_t cy = a < b;
|
||||||
|
rp[i] = a - b;
|
||||||
|
b = cy;
|
||||||
|
}
|
||||||
|
while (++i < n);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_limb_t
|
||||||
|
mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
|
||||||
|
{
|
||||||
|
mp_size_t i;
|
||||||
|
mp_limb_t cy;
|
||||||
|
|
||||||
|
for (i = 0, cy = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
mp_limb_t a, b;
|
||||||
|
a = ap[i]; b = bp[i];
|
||||||
|
b += cy;
|
||||||
|
cy = (b < cy);
|
||||||
|
cy += (a < b);
|
||||||
|
rp[i] = a - b;
|
||||||
|
}
|
||||||
|
return cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_limb_t
|
||||||
|
mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
|
||||||
|
{
|
||||||
|
mp_limb_t cy;
|
||||||
|
//assert (an >= bn);
|
||||||
|
cy = mpn_sub_n (rp, ap, bp, bn);
|
||||||
|
if (an > bn)
|
||||||
|
cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy);
|
||||||
|
return cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPZ interface */
|
||||||
|
|
||||||
|
void
|
||||||
|
mpz_clear (mpz_t r)
|
||||||
|
{
|
||||||
|
if (r->_mp_alloc)
|
||||||
|
gmp_free_limbs (r->_mp_d, r->_mp_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_ptr
|
||||||
|
mpz_realloc (mpz_t r, mp_size_t size)
|
||||||
|
{
|
||||||
|
size = gmp_max (size, 1);
|
||||||
|
|
||||||
|
if (r->_mp_alloc)
|
||||||
|
r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size);
|
||||||
|
else
|
||||||
|
r->_mp_d = gmp_alloc_limbs (size);
|
||||||
|
r->_mp_alloc = size;
|
||||||
|
|
||||||
|
if (gmp_abs (r->_mp_size) > size)
|
||||||
|
r->_mp_size = 0;
|
||||||
|
|
||||||
|
return r->_mp_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
|
||||||
|
mp_ptr mrz_realloc_if(mpz_t z,mp_size_t n) {
|
||||||
|
return n > z->_mp_alloc ? mpz_realloc(z, n) : z->_mp_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPZ comparisons and the like. */
|
||||||
|
int
|
||||||
|
mpz_sgn (const mpz_t u)
|
||||||
|
{
|
||||||
|
return gmp_cmp (u->_mp_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpz_swap (mpz_t u, mpz_t v)
|
||||||
|
{
|
||||||
|
mp_size_t_swap (u->_mp_alloc, v->_mp_alloc);
|
||||||
|
mp_ptr_swap(u->_mp_d, v->_mp_d);
|
||||||
|
mp_size_t_swap (u->_mp_size, v->_mp_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPZ addition and subtraction */
|
||||||
|
|
||||||
|
static mp_size_t
|
||||||
|
mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b)
|
||||||
|
{
|
||||||
|
mp_size_t an = gmp_abs (a->_mp_size);
|
||||||
|
mp_size_t bn = gmp_abs (b->_mp_size);
|
||||||
|
mp_ptr rp;
|
||||||
|
mp_limb_t cy;
|
||||||
|
|
||||||
|
if (an < bn)
|
||||||
|
{
|
||||||
|
mpz_srcptr_swap (a, b);
|
||||||
|
mp_size_t_swap (an, bn);
|
||||||
|
}
|
||||||
|
|
||||||
|
rp = mrz_realloc_if (r, an + 1);
|
||||||
|
cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
|
||||||
|
|
||||||
|
rp[an] = cy;
|
||||||
|
|
||||||
|
return an + cy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_size_t
|
||||||
|
mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b)
|
||||||
|
{
|
||||||
|
mp_size_t an = gmp_abs (a->_mp_size);
|
||||||
|
mp_size_t bn = gmp_abs (b->_mp_size);
|
||||||
|
int cmp;
|
||||||
|
mp_ptr rp;
|
||||||
|
|
||||||
|
cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn);
|
||||||
|
if (cmp > 0)
|
||||||
|
{
|
||||||
|
rp = mrz_realloc_if (r, an);
|
||||||
|
mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn);
|
||||||
|
return mpn_normalized_size (rp, an);
|
||||||
|
}
|
||||||
|
else if (cmp < 0)
|
||||||
|
{
|
||||||
|
rp = mrz_realloc_if (r, bn);
|
||||||
|
mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an);
|
||||||
|
return -mpn_normalized_size (rp, bn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpz_add (mpz_t r, const mpz_t a, const mpz_t b)
|
||||||
|
{
|
||||||
|
mp_size_t rn;
|
||||||
|
|
||||||
|
if ( (a->_mp_size ^ b->_mp_size) >= 0)
|
||||||
|
rn = mpz_abs_add (r, a, b);
|
||||||
|
else
|
||||||
|
rn = mpz_abs_sub (r, a, b);
|
||||||
|
|
||||||
|
r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpz_sub (mpz_t r, const mpz_t a, const mpz_t b)
|
||||||
|
{
|
||||||
|
mp_size_t rn;
|
||||||
|
|
||||||
|
if ( (a->_mp_size ^ b->_mp_size) >= 0)
|
||||||
|
rn = mpz_abs_sub (r, a, b);
|
||||||
|
else
|
||||||
|
rn = mpz_abs_add (r, a, b);
|
||||||
|
|
||||||
|
r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
|
||||||
|
}
|
66
projects/task1/mini-gmp.h
Executable file
66
projects/task1/mini-gmp.h
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
typedef unsigned long mp_limb_t;
|
||||||
|
typedef long mp_size_t;
|
||||||
|
typedef unsigned long mp_bitcnt_t;
|
||||||
|
|
||||||
|
typedef mp_limb_t *mp_ptr;
|
||||||
|
typedef const mp_limb_t *mp_srcptr;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int _mp_alloc; /* Number of *limbs* allocated and pointed
|
||||||
|
to by the _mp_d field. */
|
||||||
|
int _mp_size; /* abs(_mp_size) is the number of limbs the
|
||||||
|
last field points to. If _mp_size is
|
||||||
|
negative this is a negative number. */
|
||||||
|
mp_limb_t *_mp_d; /* Pointer to the limbs. */
|
||||||
|
} __mpz_struct;
|
||||||
|
|
||||||
|
/* mpz_t is an array type that contains a single element of __mpz_struct, acting as a reference. */
|
||||||
|
typedef __mpz_struct mpz_t[1];
|
||||||
|
typedef __mpz_struct *mpz_ptr;
|
||||||
|
typedef const __mpz_struct *mpz_srcptr;
|
||||||
|
|
||||||
|
/* BEGIN Given Functions */
|
||||||
|
|
||||||
|
/* Swap functions. */
|
||||||
|
void mp_size_t_swap(mp_size_t x, mp_size_t y);
|
||||||
|
|
||||||
|
void mp_ptr_swap(mp_ptr x, mp_ptr y);
|
||||||
|
|
||||||
|
void mpz_srcptr_swap(mpz_srcptr x, mpz_srcptr y);
|
||||||
|
|
||||||
|
/* Memory allocation functions. */
|
||||||
|
static mp_ptr
|
||||||
|
gmp_alloc_limbs (mp_size_t size);
|
||||||
|
|
||||||
|
static mp_ptr
|
||||||
|
gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size);
|
||||||
|
|
||||||
|
static void
|
||||||
|
gmp_free_limbs (mp_ptr old, mp_size_t size);
|
||||||
|
|
||||||
|
/* END Given Functions */
|
||||||
|
|
||||||
|
void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
|
||||||
|
|
||||||
|
int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t);
|
||||||
|
|
||||||
|
mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
|
||||||
|
mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
|
||||||
|
mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
|
||||||
|
|
||||||
|
mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
|
||||||
|
mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
|
||||||
|
mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
|
||||||
|
|
||||||
|
void mpz_clear (mpz_t);
|
||||||
|
|
||||||
|
int mpz_sgn (const mpz_t);
|
||||||
|
|
||||||
|
void mpz_neg (mpz_t, const mpz_t);
|
||||||
|
void mpz_swap (mpz_t, mpz_t);
|
||||||
|
|
||||||
|
void mpz_add (mpz_t, const mpz_t, const mpz_t);
|
||||||
|
void mpz_sub (mpz_t, const mpz_t, const mpz_t);
|
||||||
|
|
||||||
|
void mpz_set (mpz_t, const mpz_t);
|
225
projects/task2/cnf_trans.c
Executable file
225
projects/task2/cnf_trans.c
Executable file
@ -0,0 +1,225 @@
|
|||||||
|
#include "cnf_trans.h"
|
||||||
|
|
||||||
|
/* BEGIN Given Functions */
|
||||||
|
|
||||||
|
// 分配一个大小为size的全零的int数组
|
||||||
|
int* malloc_int_array(int size);
|
||||||
|
|
||||||
|
// 释放int数组
|
||||||
|
void free_int_array(int* array);
|
||||||
|
|
||||||
|
// 分配一个初始全零 cnf_list 结构体
|
||||||
|
cnf_list* malloc_cnf_list();
|
||||||
|
|
||||||
|
// 释放 cnf_list 结构体
|
||||||
|
void free_cnf_list(cnf_list* list);
|
||||||
|
|
||||||
|
/* END Given Functions */
|
||||||
|
|
||||||
|
|
||||||
|
//生成p3<->(p1 op p2)对应的cnf中的clause
|
||||||
|
//p3<->not p2 (op为 not时, 此时p1缺省为0)
|
||||||
|
void clause_gen(int p1, int p2, int p3, int op, PreData* data){
|
||||||
|
int size = 3;
|
||||||
|
int *clause1 = malloc_int_array(size);
|
||||||
|
int *clause2 = malloc_int_array(size);
|
||||||
|
int *clause3 = malloc_int_array(size);
|
||||||
|
int *clause4 = malloc_int_array(size);
|
||||||
|
// 完成 SET_PROP: p3<->(p1 op p2) / p3<->not p2
|
||||||
|
int cnt = 0;
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case SMTPROP_OR:
|
||||||
|
{
|
||||||
|
// p3\/非p1
|
||||||
|
clause1[0] = -p1;
|
||||||
|
clause1[1] = p3;
|
||||||
|
// p3\/非p2
|
||||||
|
clause2[0] = -p2;
|
||||||
|
clause2[1] = p3;
|
||||||
|
if (p1 != p2)
|
||||||
|
{
|
||||||
|
// 非p3\/p1\/p2
|
||||||
|
clause3[0] = p1;
|
||||||
|
clause3[1] = p2;
|
||||||
|
clause3[2] = -p3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clause3[0] = p1;
|
||||||
|
clause3[1] = -p3;
|
||||||
|
}
|
||||||
|
cnt += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMTPROP_AND:
|
||||||
|
{
|
||||||
|
// 非p3\/p1
|
||||||
|
clause1[0] = p1;
|
||||||
|
clause1[1] = -p3;
|
||||||
|
// 非p3\/p2
|
||||||
|
clause2[0] = p2;
|
||||||
|
clause2[1] = -p3;
|
||||||
|
if (p1 != p2)
|
||||||
|
{
|
||||||
|
// p3\/非p1\/非p2
|
||||||
|
clause3[0] = -p1;
|
||||||
|
clause3[1] = -p2;
|
||||||
|
clause3[2] = p3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clause3[0] = -p1;
|
||||||
|
clause3[1] = p3;
|
||||||
|
}
|
||||||
|
cnt += 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMTPROP_IMPLY:
|
||||||
|
{
|
||||||
|
if (p1 != p2)
|
||||||
|
{
|
||||||
|
// p3\/p1
|
||||||
|
clause1[0] = p1;
|
||||||
|
clause1[1] = p3;
|
||||||
|
// p3\/非p2
|
||||||
|
clause2[0] = -p2;
|
||||||
|
clause2[1] = p3;
|
||||||
|
// 非p3\/非p1\/p2
|
||||||
|
clause3[0] = -p1;
|
||||||
|
clause3[1] = p2;
|
||||||
|
clause3[2] = -p3;
|
||||||
|
cnt += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clause1[0] = p3;
|
||||||
|
cnt += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMTPROP_IFF:
|
||||||
|
{
|
||||||
|
if (p1 != p2)
|
||||||
|
{
|
||||||
|
// p3\/p1\/p2
|
||||||
|
clause1[0] = p1;
|
||||||
|
clause1[1] = p2;
|
||||||
|
clause1[2] = p3;
|
||||||
|
// p3\/非p1\/非p2
|
||||||
|
clause2[0] = -p1;
|
||||||
|
clause2[1] = -p2;
|
||||||
|
clause2[2] = p3;
|
||||||
|
// 非p3\/p1\/非p2
|
||||||
|
clause3[0] = p1;
|
||||||
|
clause3[1] = -p2;
|
||||||
|
clause3[2] = -p3;
|
||||||
|
// 非p3\/非p1\/p2
|
||||||
|
clause4[0] = -p1;
|
||||||
|
clause4[1] = p2;
|
||||||
|
clause4[2] = -p3;
|
||||||
|
cnt += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clause1[0] = p3;
|
||||||
|
cnt += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMTPROP_NOT:
|
||||||
|
{
|
||||||
|
// p3\/p2
|
||||||
|
clause1[0] = p2;
|
||||||
|
clause1[1] = p3;
|
||||||
|
// 非p3\/非p2
|
||||||
|
clause2[0] = -p2;
|
||||||
|
clause2[1] = -p3;
|
||||||
|
cnt += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//unreachable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnf_list *list1 = malloc_cnf_list();
|
||||||
|
cnf_list *list2 = malloc_cnf_list();
|
||||||
|
cnf_list *list3 = malloc_cnf_list();
|
||||||
|
cnf_list *list4 = malloc_cnf_list();
|
||||||
|
list1->size = size;
|
||||||
|
list2->size = size;
|
||||||
|
list3->size = size;
|
||||||
|
list4->size = size;
|
||||||
|
list1->clause = clause1;
|
||||||
|
list2->clause = clause2;
|
||||||
|
list3->clause = clause3;
|
||||||
|
list4->clause = clause4;
|
||||||
|
if (cnt == 1)
|
||||||
|
{
|
||||||
|
list1->next = data->cnf_res;
|
||||||
|
data->cnf_res = list1;
|
||||||
|
data->clause_cnt += 1;
|
||||||
|
free_int_array(clause2);
|
||||||
|
free_int_array(clause3);
|
||||||
|
free_int_array(clause4);
|
||||||
|
free_cnf_list(list2);
|
||||||
|
free_cnf_list(list3);
|
||||||
|
free_cnf_list(list4);
|
||||||
|
}
|
||||||
|
else if (cnt == 2)
|
||||||
|
{
|
||||||
|
list1->next = list2;
|
||||||
|
list2->next = data->cnf_res;
|
||||||
|
data->cnf_res = list1;
|
||||||
|
data->clause_cnt += 2;
|
||||||
|
free_int_array(clause3);
|
||||||
|
free_int_array(clause4);
|
||||||
|
free_cnf_list(list3);
|
||||||
|
free_cnf_list(list4);
|
||||||
|
}
|
||||||
|
else if (cnt == 3)
|
||||||
|
{
|
||||||
|
list1->next = list2;
|
||||||
|
list2->next = list3;
|
||||||
|
list3->next = data->cnf_res;
|
||||||
|
data->cnf_res = list1;
|
||||||
|
data->clause_cnt += 3;
|
||||||
|
free_int_array(clause4);
|
||||||
|
free_cnf_list(list4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list1->next = list2;
|
||||||
|
list2->next = list3;
|
||||||
|
list3->next = list4;
|
||||||
|
list4->next = data->cnf_res;
|
||||||
|
data->cnf_res = list1;
|
||||||
|
data->clause_cnt += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int prop2cnf(SmtProp* p, PreData* data){
|
||||||
|
int res = 0;
|
||||||
|
switch(p->type){
|
||||||
|
case SMTB_PROP: {
|
||||||
|
int p1 = prop2cnf(p->prop.Binary_prop.prop1, data);
|
||||||
|
int p2 = prop2cnf(p->prop.Binary_prop.prop2, data);
|
||||||
|
res = ++(data->prop_cnt);
|
||||||
|
clause_gen(p1, p2, res, p->prop.Binary_prop.op, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMTU_PROP: {
|
||||||
|
int p1 = prop2cnf(p->prop.Unary_prop.prop1, data);
|
||||||
|
res = ++(data->prop_cnt);
|
||||||
|
clause_gen(0, p1, res, p->prop.Binary_prop.op, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SMT_PROPVAR:
|
||||||
|
res = p->prop.Propvar;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//unreachable
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
14
projects/task2/cnf_trans.h
Executable file
14
projects/task2/cnf_trans.h
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#include "smt_lang.h"
|
||||||
|
|
||||||
|
struct cnf_list{
|
||||||
|
int size; //变量数量
|
||||||
|
int* clause; //clause[i]存储命题变元的编号
|
||||||
|
struct cnf_list* next;
|
||||||
|
};
|
||||||
|
typedef struct cnf_list cnf_list;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
cnf_list* cnf_res;
|
||||||
|
int prop_cnt; //命题变元数量
|
||||||
|
int clause_cnt; //转成cnf后clause的数量
|
||||||
|
} PreData;
|
42
projects/task2/smt_lang.h
Executable file
42
projects/task2/smt_lang.h
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
enum SmtPropBop{
|
||||||
|
SMTPROP_AND ,
|
||||||
|
SMTPROP_OR, SMTPROP_IMPLY, SMTPROP_IFF
|
||||||
|
};
|
||||||
|
typedef enum SmtPropBop SmtPropBop;
|
||||||
|
|
||||||
|
enum SmtPropUop{
|
||||||
|
SMTPROP_NOT = 4
|
||||||
|
};
|
||||||
|
typedef enum SmtPropUop SmtPropUop;
|
||||||
|
|
||||||
|
enum SmtPropType {
|
||||||
|
SMTB_PROP = 5,
|
||||||
|
SMTU_PROP,
|
||||||
|
SMT_PROPVAR
|
||||||
|
};
|
||||||
|
typedef enum SmtPropType SmtPropType;
|
||||||
|
|
||||||
|
struct SmtProp {
|
||||||
|
SmtPropType type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
SmtPropBop op;
|
||||||
|
struct SmtProp * prop1;
|
||||||
|
struct SmtProp * prop2;
|
||||||
|
} Binary_prop;
|
||||||
|
struct {
|
||||||
|
SmtPropUop op;
|
||||||
|
struct SmtProp *prop1;
|
||||||
|
} Unary_prop;
|
||||||
|
int Propvar; //表示将原子命题抽象成的命题变元对应的编号
|
||||||
|
} prop;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct SmtProp SmtProp;
|
||||||
|
|
||||||
|
struct SmtProplist {
|
||||||
|
SmtProp* prop;
|
||||||
|
struct SmtProplist* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct SmtProplist SmtProplist;
|
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