循环直到结果在prolog中是错误的
我试图执行一个循环,直到使用prolog的谓词输出为false。我正在实现“ wordle”游戏,这是我使用的一些相关谓词:
available_length(L):-
word(W,_), %Passing through every word W resulting from predicate word(W,C).
atom_chars(W,Y), %Adding the letters of the word W to list Y.
length1(Y,L). %Finding the length of the list.
length1([],0).
length1([_|Tail],L):-
length1(Tail,Prev),
L is Prev + 1.
上一个谓词基本上以整数为输入,并检查谓词单词(w,c)中是否存在一个单词对于该整数(其中W是单词,C是类别)。下面显示的是此谓词的知识库:
word(horse,animals).
word(panda,animals).
word(hello,greetings).
word(banana,fruits).
word(bison,animals).
word(hoard,collections).
这就是“可用_length”谓词的工作方式:
available_length(L): succeeds if there are words in the KB with length L.
Examples:
?- available_length(5).
true. %becuase there exists words with length 5 in the KB(horse,panda,hello,bison,hoard).
?- available_length(9).
false. %becuase there don't exist words with the length 9 in the KB.
随着游戏的启动,它将要求用户选择一个类别以及为他选择的单词的长度。然后,根据他选择的内容,选择了他输入的类别的随机单词,游戏开始为用户提供数量的单词猜测,等于(单词 + 1的长度)。但是,如果用户输入他选择的类别中不存在的单词的长度,则应提示他发出一条消息,说他选择的长度不存在,并且可以再次选择,直到他进入长度存在。
我在底部显示了另一个使用上述谓词“可用_length”的助手谓词,以检查用户是否输入了存在的适当长度,如果他不存在,则应向上述提到的及时消息显示。
这是执行游戏的谓词的相关部分:
play:-
write('The available categories are: '), %Not implemented yet.
nl,
write('Choose a category: '),
nl,
read(Category),
nl,
write('Choose a length: '),
nl,
read(WordLength), %Takes the length as an input from the user.
check_length, %Executes the helper predicate"check_length"shown below.
Guesses is WordLength + 1, %The rest is executed only if "check_length" succeeds.
write('Game started. You have '),
write(Guesses),
write(' guesses.'),
问题是我如何继续向用户提示用户,直到“可用_length”谓词的输出变得真实(这意味着用户输入了正确的长度) 。我已经尝试了以下助手谓词,但是它不起作用,它会提示我是否输入是否存在的长度:
check_length:-
read(WordLength),
(available_length(WordLength) = true; %Loops until the length entered does exist.
(write('There are no words with this length.'), %Otherwise,this prompt message appear.
nl,
write('Choose a length: '), %The user is allowed to choose a length again.
check_length)
).
有人知道它如何完成吗?另一个问题是如何执行用户从KB谓词选择的类别中选择一个随机单词的谓词。例如,如果他选择“动物”类别,则应随机选择三个词之一:马,熊猫和野牛。类别再次显示下面:
word(horse,animals).
word(panda,animals).
word(hello,greetings).
word(banana,fruits).
word(bison,animals).
word(hoard,collections).
I am trying to execute a loop until the output of the predicate is false using Prolog. I am implementing the "Wordle" game and here are some of the relevant predicates I am using:
available_length(L):-
word(W,_), %Passing through every word W resulting from predicate word(W,C).
atom_chars(W,Y), %Adding the letters of the word W to list Y.
length1(Y,L). %Finding the length of the list.
length1([],0).
length1([_|Tail],L):-
length1(Tail,Prev),
L is Prev + 1.
The previous predicate basically takes as an input an integer and checks whether there exists a word in the predicate word(W, C) having a length equal to that integer(where W is the word and C is the category). Shown below is the Knowledge Base of this predicate:
word(horse,animals).
word(panda,animals).
word(hello,greetings).
word(banana,fruits).
word(bison,animals).
word(hoard,collections).
This is how the "available_length" predicate works:
available_length(L): succeeds if there are words in the KB with length L.
Examples:
?- available_length(5).
true. %becuase there exists words with length 5 in the KB(horse,panda,hello,bison,hoard).
?- available_length(9).
false. %becuase there don't exist words with the length 9 in the KB.
As the game starts, it will ask the user to choose a category as well as a length for a word of his choice. Then based on what he chooses, a random word from the category he entered is chosen and the game starts giving the user a number of guesses for the word equal to the (length of the word + 1). However, if the user enters a length of a word that doesn't exist in the category he chooses, he should be prompted with a message saying that the length he choose doesn't exist and is allowed to choose again until he enters a length that exists.
I implemented another helper predicate shown at the bottom that uses the above predicate "available_length" to check whether the user entered a proper length that exists or not and if he doesn't, he should be shown a prompt message as mentioned above.
And this is the relevant part of the of the predicate that executes the game:
play:-
write('The available categories are: '), %Not implemented yet.
nl,
write('Choose a category: '),
nl,
read(Category),
nl,
write('Choose a length: '),
nl,
read(WordLength), %Takes the length as an input from the user.
check_length, %Executes the helper predicate"check_length"shown below.
Guesses is WordLength + 1, %The rest is executed only if "check_length" succeeds.
write('Game started. You have '),
write(Guesses),
write(' guesses.'),
The question is how do I keep prompting the user with the message until the output of the "available_length" predicate becomes true (meaning that the user entered a correct length). I already tried the following helper predicate, but it didn't work, it prompts the message whether I enter a length that exists or not:
check_length:-
read(WordLength),
(available_length(WordLength) = true; %Loops until the length entered does exist.
(write('There are no words with this length.'), %Otherwise,this prompt message appear.
nl,
write('Choose a length: '), %The user is allowed to choose a length again.
check_length)
).
Does anybody have a clue about how it is done? Another question is how to execute a predicate that chooses a random word in the category that the user chooses from the predicates of the KB. For example, if he chooses the "animals" category, one of the three words: horse, panda, and bison should be chosen randomly). The categories are shown again below:
word(horse,animals).
word(panda,animals).
word(hello,greetings).
word(banana,fruits).
word(bison,animals).
word(hoard,collections).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要检查给定长度的单词的可用性,您需要知道它属于哪个类别。另外,要确定原子的长度,您可以使用ISO谓词
atom_length/2
:to 阅读用户输入的术语,您可以使用谓词:
to to to to重复输入,直到输入A 有效的单词类别,请使用谓词:
示例:
重复输入,直到输入a 有效的单词长度,对于给定类别,请使用谓词:
示例:
从给定类别中选择一个随机词,您可以使用predicate
randod_member/2
:示例:
swi-prolog defines
randy_member/2 < /代码>如下:
To check the availability of a word of a given length, you need to know which category it belongs to. Also, to determine the length of an atom, you can use the ISO predicate
atom_length/2
:To read a term entered by the user, you can use the predicate:
To repeat the input until a valid word category is entered, use the predicate:
Example:
To repeat the input until a valid word length is entered, for a given category, use the predicate:
Example:
To choose a random word from a given category, you can use the predicate
random_member/2
:Examples:
SWI-Prolog defines
random_member/2
as follows:您的问题太长了。太久了。您还已经做出了几个可疑的设计选择。
借助您的数据库,在Prolog中执行此操作的一种简单方法是:
您在数据库中寻找一个
length
的单词,如果您找到一个单词,则成功。没有循环,没有递归,只有逻辑。查找“否定为失败”的含义!至少有两种方法可以做到这一点。一个是古老的“失败驱动循环”,查找这意味着什么。您确实需要
重复/0
。为了示例,跳过所有write
s:这也是 您很长的问题的标题。
另一种方法是将递归定义用作这个答案向您展示了这个答案。如果您需要保持状态,则应该更喜欢递归定义而不是失败驱动的循环。
根据您的用例,有太多方法可以随机选择一个单词。但这已经是一个新问题,所以我不会在这里回答。
Your question is too long. Way too long. You have also made several questionable design choices already.
With your database, an easy way to do this in Prolog is:
You look for a word that is
Length
long in the database, and if you find one, you succeed. No loops, no recursion, just logic. Look up what "negation as failure" means!There are at least two ways to do that. One is the venerable "failure-driven loop", look up what that means. You do need
repeat/0
for this. Skipping all thewrite
s for the sake of the example:This is also literally the title of your very long question.
The other way is to use a recursive definition as this answer showed you. You should prefer a recursive definition over a failure-driven loop if you need to keep a state.
There are too many ways to pick a word at random depending on your use case. But this is already a new question so I won't answer it here.