prolog - 不是功能警告

Wab*_*age 4 prolog

我有这个Prolog程序,我希望将玩家与具有相同级别(新手,中级或专家)和服务器的玩家匹配:

player(player29, 408, 183, europe).
player(player30, 462, 97, north-america).
player(player31, 25, 22, asia).
player(player32, 481, 248, asia).
player(player33, 111, 37, asia).
player(player34, 424, 359, north-america).
player(player35, 381, 358, asia).
player(player36, 231, 159, africa).
player(player37, 31, 20, africa).
player(player38, 22, 21, africa).
player(player39, 144, 35, oceania).
player(player40, 30, 25, asia).
player(player41, 221, 112, south-america).
player(player42, 344, 292, africa).
player(player43, 183, 148, asia).
player(player44, 62, 40, africa).
player(player45, 281, 23, north-america).
player(player46, 308, 173, south-america).
player(player47, 127, 125, asia).
player(player48, 441, 393, south-america).
player(player49, 213, 48, oceania).
player(player50, 343, 145, africa).

winrate(X):-player(X, T, W, _); (W/T) * 100.

newbie(X):-winrate(X) < 40.
intermediate(X):-winrate(X) >=40; winrate(X) < 80.
expert(X):-winrate(X) > 80.
Run Code Online (Sandbox Code Playgroud)

但是,当我编译它时,我得到一个警告说"算术:'winrate(_G1082)'不是一个函数".有人可以向我解释这意味着什么吗?

Dan*_*ons 7

如果我能在Prolog中提出一个最大的历史初学者绊脚石的误解,那就是:Prolog中没有返回值这样的东西.所以问题归结为这个定义:

winrate(X) :- player(X, T, W, _); (W/T) * 100.
Run Code Online (Sandbox Code Playgroud)

如果你只是输入Prolog,你会得到一个神秘的警告信息:

Warning: user://1:9:
    Singleton variable in branch: T
    Singleton variable in branch: W
Run Code Online (Sandbox Code Playgroud)

我怀疑你认为该条款说"为玩家X查找T和W并返回W/T*100".Prolog实际上认为你说的是​​"为玩家X查找T和W,或者在某个时间内查找一百次< 尴尬的停顿 >",这不是特别有意义.当你问的时候winrate(player47),Prolog会站在角落里,双手插在口袋里说"嗯,真的吗?"

纠正是这样的:

winrate(X, Rate) :- player(X, T, W, _), Rate is (W/T) * 100.
Run Code Online (Sandbox Code Playgroud)

newbie/1et中,你有一个完全相同的问题.al.:winrate(X) < 40在Prolog中没有内在含义,因为Prolog中没有"返回值".纠正的表达是winrate(X, WinRate), WinRate < 40.

请注意,Prolog中的最后一个参数没有什么特别之处.具有单向语义的谓词通常使用结果的最后一个参数,但它实际上不是一个法则,而Prolog并没有强制执行任何操作.

密切关注单例变量错误.如果没有变量出现多次,Prolog中没有任何有意义的事情发生,所以如果你得到这个错误而你立即用命名变量替换_,你的子句似乎仍然有足够的信息来完成它的工作吗?如果没有,你几乎肯定会错过一些东西或者对Prolog的语义感到困惑.相信我,我从经验中学到了这一点.