Prolog:在Jeopardy中编写像Watson这样的程序

时间:2015-09-12 19:45:21

标签: prolog ibm-watson

我正在尝试创建一个程序,可以找到您可以使用给定字母组创建的最长单词。 (有点像Watson在Jeopardy)

到目前为止,我设法做到这一点,如果你指定单词的长度,它会给你所有用你给它的字母所用的长度的单词。

该计划包含考虑所有英语单词的事实word/1,如下:

word(ant).  
word(computer).
% ... (and many more)

首先,我创建了一个名为word_letters/2的谓词,它将单词转换为字母列表,如atom_chars/2谓词。

然后,我写了一个cover/2谓词来查看列表是否包含前一个列表的所有字母:

cover([],[]).
cover([],_).
cover([Head1|Tail1],List2) :-
   member(Head1,List2),
   select(Head1,List2,Newlist),
   cover(Tail1,Newlist).

然后我编写了一个solution/3谓词,将一定长度的所有单词转换为一个字母列表,并检查该列表是否由您首先给出的字母覆盖:

solution(Letters,Word,Length) :-
   word(Word),
   word_letters(Word,Letters2),
   length(Letters2,Length),
   word_letters(Word,Letters2),
   cover(Letters2,Letters).

我现在要做的是做到这一点,这样你就不必指定单词的长度。它应该只给出最长的单词,并告诉你它有多长。 它应该像这样工作:

?- topsolution([g,i,g,c,n,o,a,s,t], Word, Score).
Word = agnostic,
Score = 8
True

看起来并不难,但我似乎无法让它发挥作用。 如果有人可以帮助或者指出我正确的方向,那就太好了!

1 个答案:

答案 0 :(得分:2)

您遇到的问题可以分解为 two

  1. 确定word/1词典中所有单词的最大长度。

    只要word/1的定义发生变化,这就是一次性的努力。

  2. 列举所有可接受的分数 - 从最大的分数开始,而不是从最小的分数开始。

    使用length/2append/3,您可以写:

    ?- length(Ref,7), append(_,Part,Ref).
      Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_A,_B,_C,_D,_E,_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_B,_C,_D,_E,_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_C,_D,_E,_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_D,_E,_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_E,_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_F,_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = [_G]
    ; Ref = [_A,_B,_C,_D,_E,_F,_G], Part = []
    ; false.