01 F64 KNTotal0(CHashTable *t,U8 *a,U8 *b) {
02   return RelationshipsWithWord(a,b);
03 }
04 F64 KneserNey0(CHashTable *t,U8 *a,U8 *b,F64 d=.1) {
05   I64 mask;
06   U8 buf[STR_LEN];
07   F64 top,bottom=0.,l,fb,fa;
08   CHashGeneric *gen;
09   I64 bl=StrLen(b);
10   fb=FramePtr(StrPrint(buf,"Relats.%s",b));
11   fa=FramePtr(StrPrint(buf,"Relats.%s",a));
12   top=Max(KNTotal0(t,a,b)-d,0);
13   bottom=FramePtr(StrPrint(buf,"Relats.%s",b))-top;
14   if(!bottom)
15     return 0.;
16   l=d/bottom;
17   top/=bottom;
18   return top+l*fa/ToF64(total_relats);
19 }
20 F64 KNTotal(CHashTable *t,U8 *a,U8 *b) {
21   CHashGeneric *gen;
22   U8 buf[STR_LEN];
23   F64 cnt=0;
24   I64 who=1;
25   StrPrint(buf,"%s %s",a,b);
26   while(gen=HashSingleTableFind(buf,t,HTT_FRAME_PTR,who++)) {
27      cnt+=ToF64(gen->user_data1);
28   }
29   return cnt;
30 }
31 
32 F64 KneserNey(CHashTable *t,U8 *a,U8 *b,F64 d=.1) {
33   I64 mask;
34   U8 buf[STR_LEN];
35   F64 top,bottom=0.,l,fb,fa;
36   CHashGeneric *gen;
37   I64 bl=StrLen(b);
38   fb=FramePtr(StrPrint(buf,"Relats.%s",b));
39   fa=FramePtr(StrPrint(buf,"Relats.%s",a));
40   top=Max(KNTotal(t,a,b)-d,0);
41   bottom=FramePtr(StrPrint(buf,"Relats.%s",b));
42   if(!bottom)
43     return 0.;
44   l=d/bottom;
45   top/=bottom;
46   return top+l*fa/ToF64(total_relats);
47 }