- 注册时间
- 2007-12-27
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 40149
- 在线时间
- 小时
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?欢迎注册
×
今天使用了一下cvc3,一种一阶逻辑证明工具(类似的工具还有Z3,simplify等)
起因是看到百度数学吧中一个题目:
五名网球队员参加一次双打比赛,设选手A的分数为R(A),任意两名选手的分数不同,任意2名选手的分数和也各不相同。若R(A)+R(B)>R(C)+R(D)则称(A,B)这对选手胜(C,D)这对选手。于是将(C,D)拆散,另外两队选手(C,E)或(D,E)之一与(A,B)继续下一场比赛。直到某两对以前曾经交过手的组合再次相遇(相遇时比赛停止),求比赛最多能进行多少场
由此写了一个使用cvc3的程序:- #include <stdio.h>
-
- #define A 'A'
- #define B 'B'
- #define C 'C'
- #define D 'D'
- #define E 'E'
- struct Match{
- char a,b,c,d;//a<b, c<d,a<c
- }M[15]={
- {A,B,C,D},
- {A,B,C,E},
- {A,B,D,E},
- {A,C,B,D},
- {A,C,B,E},
- {A,C,D,E},
- {A,D,B,C},
- {A,D,B,E},
- {A,D,C,E},
- {A,E,B,C},
- {A,E,B,D},
- {A,E,C,D},
- {B,C,D,E},
- {B,D,C,E},
- {B,E,C,D}
- };
- int edges[15][15];
- #define SET_EDGES(u1,v1,u2,v2) \
- edges[i][j]=1;\
-
- void init_edges()
- {
- int i,j;
- for(i=0;i<15;i++)for(j=0;j<15;j++){
- if(i==j)continue;
- if(M[i].a==M[j].a&&M[i].b==M[j].b){
- edges[i][j]=1;
- }else if(M[i].c==M[j].c&&M[i].d==M[j].d){
- if(M[i].b>M[i].d){
- edges[i][j]=1;
- }
- }else if(M[i].a==M[j].c&&M[i].b==M[j].d){
- edges[i][j]=1;
- }else if(M[i].c==M[j].a&&M[i].d==M[j].b){
- if(M[i].b>M[i].d){
- edges[i][j]=1;
- }
- }
- }
- }
-
- void dump_edges()
- {
- int i,j;
- for(i=0;i<15;i++)for(j=0;j<15;j++){
- if(edges[i][j]){
- printf("%c%c%c%c=>%c%c%c%c\n",M[i].a,M[i].b,M[i].c,M[i].d,M[j].a,M[j].b,M[j].c,M[j].d);
- }
- }
- printf("\n");
- }
-
- int best=8;
- int depth=0;
- int used[15];
- int stacks[15];
-
- void dump()
- {
- int i;
- printf("Candidate depth %d:\t",depth);
- for(i=0;i<depth;i++){
- int p=stacks[i];
- printf("%c%c%c%c ",M[p].a,M[p].b,M[p].c,M[p].d);
- }
- printf("\n");
- }
-
- static int cc;
- int check_succ()
- {
- char line[100];
- FILE *f=fopen("1.cvc","w");
- fprintf(f,"A,B,C,D,E:INT;\n");
- fprintf(f,"ASSERT A>B AND B>C AND C>D AND D>E;\n");
- int i;
- for(i=0;i<depth-1;i++){
- int p=stacks[i],q=stacks[i+1];
- if(M[p].a==M[q].a&&M[p].b==M[q].b){
- fprintf(f,"ASSERT %c+%c>%c+%c;\n",M[p].a,M[p].b,M[p].c,M[p].d);
- }else if(M[p].c==M[q].c&&M[p].d==M[q].d){
- fprintf(f,"ASSERT %c+%c>%c+%c;\n",M[p].c,M[p].d,M[p].a,M[p].b);
- }else if(M[p].a==M[q].c&&M[p].b==M[q].d){
- fprintf(f,"ASSERT %c+%c>%c+%c;\n",M[p].a,M[p].b,M[p].c,M[p].d);
- }else if(M[p].c==M[q].a&&M[p].d==M[q].b){
- fprintf(f,"ASSERT %c+%c>%c+%c;\n",M[p].c,M[p].d,M[p].a,M[p].b);
- }
- }
- fprintf(f,"CHECKSAT;");
- fclose(f);
- system("cvc3 < 1.cvc >cvc.out");
- f=fopen("cvc.out","r");
- fgets(line,100,f);
- fclose(f);
- if(strncmp(line,"Uns",3)==0){
- return 0;
- }else{
- sprintf(line,"mv 1.cvc cvc%d.cvc",cc);
- cc++;
- system(line);
- return 1;
- }
- }
-
- void search()
- {
- int i;
- int p=stacks[depth-1];
- if(depth>=best){
- if(check_succ()){
- best=depth;
- dump();
- }
- }
- for(i=0;i<15;i++){
- if(!used[i]&&edges[p][i]!=0){
- used[i]=1;stacks[depth++]=i;
- search();
- used[i]=0;depth--;
- }
- }
- }
-
- int main()
- {
- int i;
- init_edges();
- //dump_edges();
- for(i=0;i<15;i++){
- stacks[0]=i;
- used[i]=1;
- depth=1;
- search();
- used[i]=0;
- }
- }
复制代码 |
|