-
Notifications
You must be signed in to change notification settings - Fork 0
/
prolog.cpp
executable file
·116 lines (109 loc) · 3.32 KB
/
prolog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/////////////////////////////////////////////////
// Prolog-Value
TStr TPlVal::GetStr(TPlBs* PlBs) const {
TChA ChA;
if (IsInt()){ChA+=TInt::GetStr(GetInt());}
else if (IsFlt()){ChA+=TFlt::GetStr(GetFlt());}
else if (IsAtom()){ChA+=PlBs->GetAtomQStr(GetAtomId());}
else if (IsTup()){PPlTup Tup=PlBs->GetTup(GetTupId()); ChA+=Tup->GetStr(PlBs);}
else {Fail;}
return ChA;
}
/////////////////////////////////////////////////
// Prolog-Tuple
TStr TPlTup::GetStr(TPlBs* PlBs) const {
TChA ChA;
TStr RelFuncStr=PlBs->GetAtomQStr(GetFuncId());
ChA+=TStr::Fmt("%s(", RelFuncStr.CStr());
int Vals=GetVals();
for (int ValN=0; ValN<Vals; ValN++){
if (ValN>0){ChA+=", ";}
TStr ValStr=GetVal(ValN).GetStr(PlBs);
ChA+=ValStr.CStr();
}
ChA+=")";
return ChA;
}
/////////////////////////////////////////////////
// Prolog-Base
const TFSet TPlBs::TupExpect(syStr);
const TFSet TPlBs::ExpExpect(syInt, syFlt, syStr);
TPlVal TPlBs::ParseTup(TILx& Lx, const TFSet& Expect, const PPlBs& PlBs){
IAssert(TupExpect.In(Lx.Sym));
int FuncId=PlBs->AtomH.AddKey(Lx.Str);
TPlValV ValV;
Lx.GetSym(syLParen);
Lx.GetSym(ExpExpect);
TPlVal Val=ParseExp(Lx, TFSet()|syComma|syRParen, PlBs);
ValV.Add(Val);
while (Lx.Sym==syComma){
Lx.GetSym(ExpExpect);
Val=ParseExp(Lx, TFSet()|syComma|syRParen, PlBs);
ValV.Add(Val);
}
Lx.GetSym(Expect);
// create and store tuple
PPlTup Tup=TPlTup::New(FuncId, ValV);
int TupId=PlBs->AddTup(Tup);
TPlVal TupVal; TupVal.PutTupId(TupId);
return TupVal;
}
TPlVal TPlBs::ParseExp(TILx& Lx, const TFSet& Expect, const PPlBs& PlBs){
IAssert(ExpExpect.In(Lx.Sym));
TPlVal PlVal;
if (Lx.Sym==syInt){
PlVal.PutInt(Lx.Int);
Lx.GetSym(Expect);
} else
if (Lx.Sym==syFlt){
PlVal.PutFlt(Lx.Flt);
Lx.GetSym(Expect);
} else
if (Lx.Sym==syStr){
if (Lx.PeekSym()==syLParen){
Fail;
} else {
int AtomId=PlBs->AtomH.AddKey(Lx.Str);
PlVal.PutAtomId(AtomId);
Lx.GetSym(Expect);
}
} else {
Fail;
}
return PlVal;
}
PPlBs TPlBs::LoadTxtPl(const TStr& FNmWc){
PPlBs PlBs=TPlBs::New();
printf("Loading Prolog from '%s'...\n", FNmWc.CStr());
TFFile FFile(FNmWc); TStr FNm;
while (FFile.Next(FNm)){
printf(" ...loading '%s'\n", FNm.CStr());
// process prolog-file
PSIn SIn=TFIn::New(FNm);
TILx Lx(SIn, TFSet()|/*iloList|*/iloCmtAlw|iloCsSens|iloUniStr|iloExcept);
Lx.GetSym(TFSet(TupExpect)|syEof);
while (Lx.Sym!=syEof){
TPlVal TupVal=TPlBs::ParseTup(Lx, TFSet()|syPeriod, PlBs);
int FuncId=PlBs->TupV[TupVal.GetTupId()]->GetFuncId();
int Arity=PlBs->TupV[TupVal.GetTupId()]->GetVals();
PlBs->FuncIdArityPrToTupIdVH.
AddDat(TIntPr(FuncId, Arity)).Add(TupVal.GetTupId());
Lx.GetSym(TFSet(TupExpect)|syEof);
}
//break;
}
printf("Done.\n");
return PlBs;
}
void TPlBs::SaveTxt(const TStr& FNm){
TFOut FOut(FNm); FILE* fOut=FOut.GetFileId();
for (int RelId=0; RelId<GetRels(); RelId++){
for (int TupN=0; TupN<GetRelTups(RelId); TupN++){
int TupId=GetRelTupId(RelId, TupN);
PPlTup Tup=GetTup(TupId);
TStr TupStr=Tup->GetStr(this);
fprintf(fOut, "%s.\n", TupStr.CStr());
}
if (RelId+1<GetRels()){fprintf(fOut, "\n");}
}
}