必须从给定字母PROLOG列表中找到可能最长的单词

时间:2017-09-13 18:40:50

标签: list prolog

:-consult(words.pl). % words is basically a big database of the 
                     % 30.000 most used words in the english language

topsolution([], _, P) :- %basecase, in case the given list of letters is
                         %empty, output no word and give the amount of letters
                         %and call it P
    word(X),             %sees if X is a word
    P = 0.
topsolution(WordList, X, P) :- %Makes the longest word it can out of a list 
                               %of letters and outputs said word as X, and the 
                               %amount of letters it has as P
    Y = 0,                        
    solution(WordList, X, Y), %Determines what words you can make with a given
                              %list of letters and a given length of said word
    Y1 is Y + 1,             
    solution(WordList, X, Y1), %Determines the longest word of Y + 1 
    wordLength(P, X).          %Defines how many letters a word X has and calls that amount P

所以这是我为找到这个词所做的一段代码。我正在努力解决的唯一问题是我无法找到使递归停止的方法。目前,如果我输入:

?- topsolution([g,i,g], Word, Y). 

Prolog输出:

false

即使它应该输出:

Word = gig 
Y = 3
true

我知道为什么会这样做。这是因为Y将继续增加1,直到它达到Y = 4.因为没有可能的单词,其中4个字母只包含3个字母。这显然失败了。

那你们怎么建议修理这个呢?如果它遇到无法输出单词的情况,我怎么能告诉prolog它应该停止?

1 个答案:

答案 0 :(得分:1)

由于单例值警告,您应该对您的基本情况非​​常怀疑。将Prolog中的单身人士视为错误对你来说很重要,因为它们总是代表你和Prolog之间的误解。

我认为你的基本情况是错误的。当Prolog无法统一时,它将输出false;这正是应该发生的事情。如果您致电topsolution([g,g,g,g], Word, P),则应输出false而不是P = 0,而不是Word。没有解决方案。要说P = 0就是说"我找到了一个长度为0的解决方案,但我并没有告诉你它是什么。"最好说"我没有找到解决方案。"

我认为你确实有两个案例:

  1. 我根据我在这里的字母的排列找到了一个单词
  2. 我通过在我这里的一些字母上尝试#1来找到一个单词
  3. 你的基本案例实际上是#1:我手头的是一个单词的字母排列,这里是单词:

    topsolution(Letters, Word, P) :-
        permutation(Letters, WordLetters),  % permute the letters
        atom_chars(Word, WordLetters),      % make a permuted atom
        word(Word),                         % guard: it's a word
        length(Letters, P).                 % what's its length?
    

    然后你的归纳案就是删掉一封信再试一次:

    topsolution(Letters, Word, P) :-
        select(_, Letters, RemainingLetters),    % remove a letter
        topsolution(RemainingLetters, Word, P).  % try again
    

    当您在耗尽序列中的每个字母的所有排列后进入第二个谓词体时,递归将停止。 select(_, [], _)是假的。所以这里没有P = 0的担忧。