Debugging 理解Prolog函数,如何间歇打印结果

Debugging 理解Prolog函数,如何间歇打印结果,debugging,printing,prolog,nlp,viterbi,Debugging,Printing,Prolog,Nlp,Viterbi,我正在努力理解以下序言代码: most_probable_hmm_path(Words,Path) :- probable_paths(Words,[1-[start]],PPaths), keymax(PPaths,_P-Path1), reverse(Path1,[start|Path]). probable_paths([],PPaths,PPaths). probable_paths([Word|Words],PPaths0,PPaths) :- findall(PPa

我正在努力理解以下序言代码:

most_probable_hmm_path(Words,Path) :-
  probable_paths(Words,[1-[start]],PPaths),
  keymax(PPaths,_P-Path1),
  reverse(Path1,[start|Path]).

probable_paths([],PPaths,PPaths).
probable_paths([Word|Words],PPaths0,PPaths) :-
  findall(PPath,
      (outprob(Word,Tag2,PL),
      findall(P2-[Tag2,Tag1|Tags],
          (member(P1-[Tag1|Tags],PPaths0),
          transprob(Tag1,Tag2,PT), 
          P2 is PL*PT*P1),
      AllPaths),
      keymax(AllPaths,PPath)),
  PPaths1),
  probable_paths(Words,PPaths1,PPaths).

keymax(AllPaths,U-V) :-
    aggregate(max(N,P), member(N-P,AllPaths), max(U,V)).
它是维特比算法的一个实现

我想了解代码中不同位置的数据结构是如何填充的,它们是什么样子的。是否可以在算法中穿插与“print”语句等效的语句,这样我就可以看到每一步都发生了什么?我经常在用Java或Python编写代码时这样做,我发现这或多或少是一种“摸索”程序本质的有用机制

如果您感兴趣,我使用它的概率如下:

outprob(a,det,0.300).
outprob(can,aux,0.010).
outprob(can,v,0.005).
outprob(can,n,0.001).
outprob(he,pron,0.070).

transprob(start,det,0.30).          transprob(v,det,0.36).
transprob(start,aux,0.20).          transprob(v,aux,0.01).
transprob(start,v,0.10).            transprob(v,v,0.01).
transprob(start,n,0.10).            transprob(v,n,0.26).
transprob(start,pron,0.30).         transprob(v,pron,0.36).
transprob(det,det,0.20).            transprob(n,det,0.01).
transprob(det,aux,0.01).            transprob(n,aux,0.25).
transprob(det,v,0.01).              transprob(n,v,0.39).
transprob(det,n,0.77).              transprob(n,n,0.34).
transprob(det,pron,0.01).           transprob(n,pron,0.01).
transprob(aux,det,0.18).            transprob(pron,det,0.01).
transprob(aux,aux,0.10).            transprob(pron,aux,0.45).
transprob(aux,v,0.50).              transprob(pron,v,0.52).
transprob(aux,n,0.01).              transprob(pron,n,0.01).
transprob(aux,pron,0.21).           transprob(pron,pron,0.01).
检查结果如下:

?- most_probable_hmm_path([he,can,can,a,can],Sequence).
Sequence = [pron, aux, v, det, n].

在逻辑编程中,使用打印来查看程序中发生了什么是一个坏主意。这主要是因为Prolog回溯到以前创建的选择点,并且可能经过多次相同的打印。在实现Viterbi时,始终使用您将求和的对数概率,而不是相乘时可能变得非常非常小的概率。@TudorBerariu感谢您的见解,我甚至没有考虑它。说到Prolog,我几乎是一个完全的新手。你能建议我用其他方法解构这个程序来理解它的组成部分吗?我建议你把事实简化一点:只保留两个或三个隐藏状态及其相应的跃迁和发射概率分布。然后,您可以使用trace/0查看Prolog如何满足您的目标。@TudorBerariu这绝对是个好主意。我在想,我还可以向Prolog引擎提出一些其他查询,这些查询可以告诉我一些其他信息,例如,我在原始问题中包含的查询告诉我序列,尽管我猜我也可以让Prolog告诉我序列和该序列的确切数字概率,我想它会保存为列表索引的键,不是吗?你知道如何最好地表达这样的疑问吗?或者,您可能知道还有什么可能是向Prolog提出的有用查询。