9. 对简易几何机械化证明的进一步研究 第9页
CondN,CondK,ResN:Byte; //已知条件数和有几种参数以及需证结论数
Can:Array[1..9]Of TSetCh; //参与某一运算符的标识
End;
STheorem=Array[1..Max]Of ^String[5];
RTheorem=Record //一条定理的信息
MarkI:RMark; //运算符号信息
ParamI:TParamI; //参数表
Cond,Res:STheorem; //条件和结论的储存表
Can:Array[1..9]Of TSetCh; //参与某一运算符的标识
CondN,CondK,ResN,Scope:Byte;//参数数目,有几种参数,有几个结论,考虑范围
End;
TTheorem=Array[1..Max]Of ^RTheorem;//定理存储表
TResCon=Array[1..Max]Of ^RConAdr; //需证结论的 Con 地址储存表
TConData=Array[1..3,1..3]Of Byte; //临时储存 Con 地址
Var
Fl:Text; //文件变量
Con:TCon; //Con 表
Inf:TInf; //全局信息
Def:DefNum; //Def 值表
Fn:TFileName; //文件名信息
ResCon:TResCon; //结论的 Con 地址表
Theorem:TTheorem; //公式定理记录表
{================================Procedure Init=============================}
Procedure Init;
Var I,J,K:Word;L:Char;
Begin
With Inf Do
Begin
Step:=0;
MarkSet:=['{','}','[',']'];
For I:=0 To 3 Do
Inf.ParamI[I].Num:=0;
For I:=1 to 9 Do Can[i]:=[];
For L:='1' To '9' Do MarkI.MarkN[L]:=0;
End;
For L:='A' To 'z' Do Inf.Used[L].Flag:=False;
For I:=MinCb to MaxCb Do
For J:=MinCc to MaxCc Do
For K:=MinCa to MaxCa Do
Begin
Con[K,I,J].Flag:=0;//初始化 Con 表 Boolean 域为假
9
10. 对简易几何机械化证明的进一步研究 第10页
Con[K,I,J].Num:=0;
End;
With Def Do
Begin
For L:= 'A' to 'Z' Do Lable[L]:=Ord(L)-54;
For L:= 'a' to 'z' Do Lable[L]:=Ord(L)-76;
Mark['1'].Lab:='属于';Mark['1'].Num:=1;
Mark['2'].Lab:='不属于';Mark['2'].Num:=2;
Mark['3'].Lab:='包含于';Mark['3'].Num:=3;
Mark['4'].Lab:='不包含于';Mark['4'].Num:=4;
Mark['5'].Lab:='平行';Mark['5'].Num:=5;
Mark['6'].Lab:='垂直';Mark['6'].Num:=6;
Mark['7'].Lab:='异面';Mark['7'].Num:=7;
Mark['8'].Lab:='相交';Mark['8'].Num:=8;
Mark['9'].Lab:='=等于';Mark['9'].Num:=9;
End;
End;
{=============================Procedure Con==============================}
Procedure MakeCon(St:String;Var A:TConData);
Var Len:Byte;
Begin
Len:=Length(St);
If Len=3
Then Begin
A[1,1]:=Def.Lable[St[1]];
A[1,2]:=Def.Mark[St[2]].Num;
A[1,3]:=Def.Lable[St[3]];
End
Else Begin
A[1,1]:=Def.Lable[St[1]];
A[1,3]:=Def.Lable[St[3]];
A[2,1]:=Def.Lable[St[5]];
A[2,3]:=Def.Lable[St[1]];
A[3,1]:=Def.Lable[St[5]];
A[3,3]:=Def.Lable[St[3]];
A[1,2]:=8;
If Inf.Lable[St[5]]=0
Then Begin A[2,2]:=1;A[3,2]:=1;End
Else Begin A[2,2]:=3;A[3,2]:=3;End;
End;
End;
10
11. 对简易几何机械化证明的进一步研究 第11页
{============================Procedure Print=============================}
Procedure Print(St:String[5];IsOK:Boolean);
Var Adr:TConData;Tmp:Rcon;Ad:RConAdr;I,J,N:Byte;
Begin
If (Not IsOK)
Then Writeln(Fl,'结论',St,'在',Inf.StepN,'步之内无法证明!')
Else Begin
MakeCon(St,Adr);
Dec(Inf.Left);
WritelN(Fl,St[1]+Def.Mark[St[2]].Lab+St[3],'已经被证!');
End;
End;
{==============================Procedure CheckWork=======================}
Procedure CheckWork(N:Byte);
VAR DB:Array['A'..'z']Of Char;//标识符替换表
A,B:Array[1..10] of Byte;
C,D:Array[1..10] of Boolean;
I,J:Byte;Ch:Char;
Now1,Now2:TNowCan; //记录全局和定理中用到的标识符
Tmp,Stp:String;
Adr:TConData;
YN:Boolean; //次定理是否可推出信息
Link:TUp;
Procedure ZuHe(N1,M1,L1:Byte);
Var i,j:Byte;
Procedure Check;
Var I,L:Byte;
Begin
For I:=1 To M1 Do DB[Now2[L1,i]]:=Now1[L1,B[i]];
If L1=3 Then Begin
YN:=True;I:=0;J:=0;
While (YN)And(I<Theorem[N]^.CondN) Do
Begin
Inc(I);
Stp:=Theorem[N]^.Cond[I]^;
If Length(Stp)=3
Then Begin
Tmp:=DB[Stp[1]]+Stp[2]+DB[Stp[3]];
MakeCon(Tmp,Adr);
If (Con[Adr[1,1],Adr[1,2],Adr[1,3]]=Nil)
Then YN:=False
11
12. 对简易几何机械化证明的进一步研究 第12页
Else Begin
Inc(J);New(Link[J]);
Link[J]^.N1:=Adr[1,1];
Link[J]^.N2:=Adr[1,2];
Link[J]^.N3:=Adr[1,3];
End{If Else}
End{Then}
Else Begin
Tmp:=DB[Stp[1]]+Stp[2]+DB[Stp[3]]+Stp[4]+DB[Stp[5]];
MakeCon(Tmp,Adr);
If (Con[Adr[1,1],Adr[1,2],Adr[1,3]]=Nil)
Or(Con[Adr[2,1],Adr[2,2],Adr[2,3]]=Nil)
Or(Con[Adr[3,1],Adr[3,2],Adr[3,3]]=Nil)
Then YN:=False
Else Begin
Inc(J);New(Link[J]);
Link[J]^.N1:=Adr[1,1];Link[J]^.N2:=Adr[1,2];Link[J]^.N3:=Adr[1,3];
Inc(J);New(Link[J]);
Link[J]^.N1:=Adr[2,1];Link[J]^.N2:=Adr[2,2];Link[J]^.N3:=Adr[2,3];
Inc(J);New(Link[J]);
Link[J]^.N1:=Adr[3,1];Link[J]^.N2:=Adr[3,2];Link[J]^.N3:=Adr[3,3];
End;{If Else}
End;{Else}
End;{While}
If YN Then Begin
For I:=1 To Theorem[N]^.ResN Do
Begin
Inc(Inf.Step);
Stp:=Theorem[N]^.Res[I]^;
Tmp:=DB[Stp[1]]+Stp[2]+DB[Stp[3]];
MakeCon(Tmp,Adr);
If Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Flag=2
Then Print(Tmp,True)
Else If Con[Adr[1,1],Adr[1,2],Adr[1,3]]=Nil
Then Begin
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]);
Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Flag:=1;
Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Num:=J;
For L:=1 To J Do
Begin
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Up[L]);
Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Up[L]^.N1:=Link[L]^.N1;
End;
12
13. 对简易几何机械化证明的进一步研究 第13页
End;{Else If Then}
Str(Adr[1,2],Stp);Ch:=Stp[1];
If Not(Def.Mark[Ch].Lab In Inf.MarkSet)
Then If (Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Flag=2)
And(Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Flag<>2)
Then Print(Tmp,True)
Else If Con[Adr[1,3],Adr[1,2],Adr[1,1]]=Nil
Then Begin
New(Con[Adr[1,3],Adr[1,2],Adr[1,1]]);
Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Flag:=1;
Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Num:=J;
For L:=1 To J Do
Begin
New(Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Up[L]);
Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Up[L]^:=Link[L]^;
End;
End;{Else If Then}
If Inf.Left=0 Then Begin Close(Fl);Halt; End;
End;{For I}
End;{End If}
End
Else ZuHe(Inf.ParamI[L1+1].Num,Theorem[N]^.ParamI[L1+1].Num,L1+1);
End;{Check}
Procedure ZHWork;
Procedure PLTry(Dep2:Byte);
Var I:Byte;
Begin
For I:=1 To M1 Do
If C[I] then
Begin
B[Dep2]:=A[I];
C[I]:=False;
If Dep2=M1 Then Check
Else PLTry(Dep2+1);
C[i]:=True;
End;
End;{ZHWork}
Begin
Fillchar(C,sizeof(C),True);
PLTry(1);
End;{ZHWork}
Procedure ZHTry(Dep1:Byte);
Var I:Byte;
13
14. 对简易几何机械化证明的进一步研究 第14页
Begin
If Theorem[N]^.ParamI[L1].Num>0
Then Begin
If Dep1<=M1
Then Begin
For I:=1 To N1 Do
If D[I] Then
Begin
A[Dep1]:=I;
D[I]:=False;
If Dep1=M1 Then ZHWork
Else ZHTry(Dep1+1);
D[I]:=True;
End
End
End
Else Begin
If L1<>3
Then ZuHe(Inf.ParamI[L1+1].Num,Theorem[N]^.ParamI[L1+1].Num,L1+1)
Else Check;
End;
End;{ZHTry}
Begin
FillChar(D,Sizeof(D),True);
ZHTry(1);
End;{ZuHe}
Begin
If (Theorem[N]^.Scope<=Inf.Scope)And
(Theorem[N]^.CondK<=Inf.CondK)And
(Theorem[N]^.CondN<=Inf.CondN)And
(Theorem[N]^.MarkI.Kind<=Inf.MarkI.Kind)
Then Begin
For I:=0 To 3 Do
If Inf.ParamI[I].Num<Theorem[N]^.ParamI[I].Num
Then Exit;
For Ch:='1' To '9' Do
If Inf.MarkI.MarkN[Ch]<Theorem[N]^.MarkI.MarkN[Ch]
Then Exit;
End
Else Exit;
For I:=0 To 3 Do
Begin
14
15. 对简易几何机械化证明的进一步研究 第15页
For J:=1 To Inf.ParamI[I].Num Do
Now1[I,J]:=Inf.ParamI[I].ParamCh[J];
For J:=1 To Theorem[N]^.ParamI[I].Num Do
Now2[I,J]:=Theorem[N]^.ParamI[I].ParamCh[J];
End;
ZuHe(Theorem[N]^.ParamI[0].Num,Inf.ParamI[0].Num,0);
End;
{===============================Procedure ReadIn==========================}
Procedure ReadIn;
Var F:Text;Tmp:Char;
Tmps:String[5];
Adr:TConData;
Tmp1,Tmp2,TmpN,i,j:Byte;
Begin
Write('请输入已知条件和需证结论的存储路径及条件名:');
Readln(Fn.Inn);
Write('请输入保存证明结果的存储路径及条件名:');
Readln(Fn.Outn);
Write('是否使用自建知识库(Y/N) '); :
Readln(Tmp);
Write('多少步未得出结果就停止:');
Readln(Inf.StepN);
If (Tmp='Y')Or(Tmp='y') Then Fn.Flag:=True
Else Fn.Flag:=False;
If Fn.Flag=True Then
Begin
Write('请输入自建知识库的存储路径及条件名:');
Readln(Fn.Datan);
End;
Assign(F,Fn.Inn);Reset(F); //初始化输入文件
Assign(Fl,Fn.Outn);Rewrite(Fl);//初始化输出文件
With Inf Do
Begin
For Tmp:='1' To '9' Do MarkI.MarkN[Tmp]:=0;
Readln(F,CondK,CondN,ResN,MarkI.Kind,Scope);//读完第 1 行信息
Left:=ResN;
For I:=1 to CondK Do
Begin
Read(F,Tmp1,Tmp2);Read(F,Tmp);
ParamI[Tmp1].Num:=Tmp2;
Readln(F,ParamI[Tmp1].ParamCh);//读完第 2 行信息
For J:=1 to ParamI[Tmp1].Num Do
15
16. 对简易几何机械化证明的进一步研究 第16页
Begin
Used[ParamI[Tmp1].ParamCh[j]].Flag:=True;
Used[ParamI[Tmp1].ParamCh[j]].Kind:=Tmp1;
End;{For J}
End;{For I}
For I:=1 to CondN Do
Begin
Tmps:='';Read(F,Tmp);
While Tmp<>'.' Do
Begin
Tmps:=Tmps+Tmp;
Read(F,Tmp);
End;{While}
If Length(Tmps)=3
Then Begin
MakeCon(Tmps,Adr);
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]);
Str(Adr[1,2],Tmps);Tmp:=Tmps[1];
If Not(Def.Mark[Tmp].Lab In MarkSet)
Then Con[Adr[1,3],Adr[1,2],Adr[1,1]]^.Flag:=1;
Inc(MarkI.MarkN[Tmps[2]]);//累加某个运算符号出现的次数
End{Then}
Else Begin
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]);
New(Con[Adr[1,3],Adr[1,2],Adr[1,1]]);
Inc(MarkI.MarkN[Tmps[2]]);
New(Con[Adr[2,1],Adr[2,2],Adr[2,3]]);
Str(Adr[2,2],Tmps);Tmp:=Tmps[1];
Inc(MarkI.MarkN[Def.Mark[Tmp].Lab]);
New(Con[Adr[3,1],Adr[3,2],Adr[3,3]]);
Str(Adr[3,2],Tmps);Tmp:=Tmps[1];
Inc(MarkI.MarkN[Def.Mark[Tmp].Lab]);
End;{Else}
End;{For I}//读完第 2+N 行信息
Readln(F);
For I:=1 to ResN Do
Begin
Tmps:='';Read(F,Tmp);
While Tmp<>'.' Do
Begin
Tmps:=Tmps+Tmp;
Read(F,Tmp);
End;
16
17. 对简易几何机械化证明的进一步研究 第17页
If Length(Tmps)=3
Then Begin
MakeCon(Tmps,Adr);
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]);
Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Flag:=2;
End{Then}
Else Begin
New(Con[Adr[1,1],Adr[1,2],Adr[1,3]]);
Con[Adr[1,1],Adr[1,2],Adr[1,3]]^.Flag:=2;
New(Con[Adr[2,1],Adr[2,2],Adr[2,3]]);
Con[Adr[2,1],Adr[2,2],Adr[2,3]]^.Flag:=2;
New(Con[Adr[3,1],Adr[3,2],Adr[3,3]]);
Con[Adr[3,1],Adr[3,2],Adr[3,3]]^.Flag:=2;
End;
End;{For I}//读完第 3+N 行信息
End;{With Inf}
Close(F);
End;
{=============================Procedure ReadData==========================}
Procedure ReadData;
Var F:Text;Tmp:Char;Tmps:String[5];
Tmp1,Tmp2,i,j,k,N5:Byte;
Adr:TConData;
Begin
Assign(F,Fn.Datan);Reset(F);K:=0;
While (Not Eof(F)) Do
Begin
Inc(K);
New(Theorem[K]);
For I:=0 To 3 Do
Theorem[K]^.ParamI[I].Num:=0;
With Theorem[K]^ Do
Begin
For Tmp:='1' To '9' Do MarkI.MarkN[Tmp]:=0;
Readln(F,CondK,CondN,ResN,MarkI.Kind,Scope);//读完第 1 行信息
For I:=1 to CondK Do
Begin
Read(F,Tmp1,Tmp2);Read(F,Tmp);
ParamI[Tmp1].Num:=Tmp2;
Readln(F,ParamI[Tmp1].ParamCh);//读完第 2 行信息
End;{For I}
For I:=1 to CondN Do
17
18. 对简易几何机械化证明的进一步研究 第18页
Begin
New(Cond[I]);
Tmps:='';Read(F,Tmp);
While Tmp<>'.' Do
Begin
Tmps:=Tmps+Tmp;
Read(F,Tmp);
End;{While}
Cond[I]^:=Tmps;
If Length(Tmps)=3
Then Inc(MarkI.MarkN[Tmps[2]])
Else Begin
MakeCon(Tmps,Adr);
Inc(MarkI.MarkN['^']);
Str(Adr[2,2],Tmps);Tmp:=Tmps[1];
Inc(MarkI.MarkN[Def.Mark[Tmp].Lab]);
Str(Adr[3,2],Tmps);Tmp:=Tmps[1];
Inc(MarkI.MarkN[Def.Mark[Tmp].Lab]);
End;
End;{For I}
Readln(F);//读完第 2+N 行信息
For I:=1 to ResN Do
Begin
New(Res[I]);
Tmps:='';Read(F,Tmp);
While Tmp<>'.' Do
Begin
Tmps:=Tmps+Tmp;
Read(F,Tmp);
End;
Res[I]^:=Tmps;
End;{For I}//读完第 3+N 行信息
Readln(F);
End;{With}
Readln(F);
End;{While}
Inf.ThN:=K;
Close(F);
End;
{==============================Procedure Prove==============================}
Procedure Prove;
Var I:Byte;
18
19. 对简易几何机械化证明的进一步研究 第19页
Begin
While (Inf.Step<=Inf.StepN)And(Inf.Left>0) Do
For I:=1 To Inf.ThN Do
CheckWork(I);
If Inf.Step>=Inf.StepN Then Print('',False);
End;
{=====================================Main==================================}
Begin
Init;
ReadIn;
ReadData;
Prove;
Close(Fl);
End.
19