在 Prolog 中计算函子内部的函子
Evaluating functors inside a functor in Prolog
我正在阅读 John Stobo 的 Prolog solving with Prolog 一书。我已经学习了第 1 章(根据事实编程)和第 2 章(根据规则编程)现在我在第 3 章:R规则中的递归 我正在练习第 3.1 节中给出的程序。我已经对程序进行了一些阐述(没有改变主要结构)并添加了我自己的仿函数(或函数或规则?)命名为 is_rank_lower/2
但它没有按预期工作。
当我输入(或询问 Prolog)时
is_rank_lower(ryan, jondoe).
输出是
错误。
预期输出:true。
因为ryan是二等兵,jondoe是下士,二等兵的军衔低于下士。
解释在代码中。
问题 #1:如何使我自己的仿函数 is_lower_rank 按预期工作?
问题 #2:这个问题可能与本书有关,因为当我按原样写下程序时,它会稍微出错,这可能是我自己的原因仿函数也会错误地运行。只是猜测。
当我输入:
lower_rank(二等兵,下士)。
Prolog returns 和 true
并等待它,我必须在 true
后面放一个点然后单击 enter 然后才 return ?-
提示。
预期输出为:
return 与 true.
然后 return 到 ?-
提示
作者好像在说这个问题。在第 57 页,他写道“如果目标失败,lower_rank 将不会终止”我已经应用了所有指令,但仿函数仍然不起作用。如何让它发挥作用?
我的序言版本swi-prolog 7.2.0
% John Stobo, problem solving with Prolog, March.1989
% FACTS:
next_degree(private, corporal).
next_degree(corporal, sergeant).
next_degree(sergeant, lieutenant).
next_degree(lieutenant, captain).
next_degree(captain, major).
next_degree(major, "lieutenant colonel").
next_degree("lieutenant colonel", colonel).
next_degree(colonel, "brigadier general").
next_degree("brigadier general", "major general").
next_degree("major general","lieutenant general").
next_degree("lieutenant general", general).
soldier(ryan, private).
soldier(jondoe, corporal).
sooldier(smartson, captain).
% RULES:
lower_rank(R1, R2) :-
next_degree(R1, R2).
lower_rank(R1, R2) :- % this works but if
next_degree(R1, R3), % the result is "true"
lower_rank(R3, R2). % it doesn't end properly
% only if the user types a dot, it ends properly
is_rank_lower(A1,A2) :-
lower_rank(soldier(A1,X), soldier(A2,X)).
% doesn't work because the functors are inserted as
% 'soldier(ryan, _G1471), soldier(jondoe, _G1471))
% not as private, corporal, i.e. they are not evaluated
next_degree/2 似乎是一种奇怪的方法 - 书中建议它是明智的,还是作为不该做的例子?
https://swi-prolog.discourse.group/t/useful-prolog-references/1089
有不错的书
这个有效:
% First argument is an atom, hence single quotes in swi-prolog
rank_order(private, 1).
rank_order(corporal, 2).
rank_order(sergeant, 3).
rank_order(lieutenant, 4).
rank_order(captain, 5).
rank_order(major, 6).
rank_order('lieutenant colonel', 7).
rank_order(colonel, 8).
rank_order('brigadier general', 9).
rank_order('major general', 10).
rank_order('lieutenant general', 11).
soldier(ryan, private).
soldier(jondoe, corporal).
% Not mis-spelled as "sooldier"
soldier(smartson, captain).
rank_lower(RankLower, RankUpper) :-
rank_order(RankLower, RankLowerOrder),
rank_order(RankUpper, RankUpperOrder),
RankLowerOrder < RankUpperOrder.
soldier_rank_lower(SoldierLower, SoldierUpper) :-
soldier(SoldierLower, RankLower),
soldier(SoldierUpper, RankUpper),
rank_lower(RankLower, RankUpper).
结果 swi-prolog:
?- rank_lower(private, corporal).
true.
?- soldier_rank_lower(ryan, jondoe).
true.
?- soldier_rank_lower(L, U).
L = ryan,
U = jondoe ;
L = ryan,
U = smartson ;
L = jondoe,
U = smartson ;
false.
第二次尝试:
rank_next(private, corporal).
rank_next(corporal, sergeant).
rank_next(sergeant, lieutenant).
rank_next(lieutenant, captain).
rank_next(captain, major).
rank_next(major, 'lieutenant colonel').
rank_next('lieutenant colonel', colonel).
rank_next(colonel, 'brigadier general').
rank_next('brigadier general', 'major general').
rank_next('major general', 'lieutenant general').
rank_next('lieutenant general', general).
soldier(ryan, private).
soldier(jondoe, corporal).
soldier(smartson, captain).
rank_lower(RankLower, RankUpper) :-
rank_next(RankLower, RankLower1),
% Increase lower to eventually meet with upper
( RankLower1 = RankUpper ;
rank_lower(RankLower1, RankUpper)
).
soldier_rank_lower(SoldierLower, SoldierUpper) :-
soldier(SoldierLower, RankLower),
soldier(SoldierUpper, RankUpper),
% Won't have multiple answers
once(rank_lower(RankLower, RankUpper)).
这使得以下内容具有确定性:
?- soldier_rank_lower(ryan, jondoe).
true.
...同时保持rank_lower/2的一般性,即:
?- findall(L-U, rank_lower(L, U), Pairs), length(Pairs, Len).
Pairs = [private-corporal,private-sergeant,private-lieutenant, ...
Len = 66.
我正在阅读 John Stobo 的 Prolog solving with Prolog 一书。我已经学习了第 1 章(根据事实编程)和第 2 章(根据规则编程)现在我在第 3 章:R规则中的递归 我正在练习第 3.1 节中给出的程序。我已经对程序进行了一些阐述(没有改变主要结构)并添加了我自己的仿函数(或函数或规则?)命名为 is_rank_lower/2
但它没有按预期工作。
当我输入(或询问 Prolog)时
is_rank_lower(ryan, jondoe).
输出是
错误。
预期输出:true。
因为ryan是二等兵,jondoe是下士,二等兵的军衔低于下士。
解释在代码中。
问题 #1:如何使我自己的仿函数 is_lower_rank 按预期工作?
问题 #2:这个问题可能与本书有关,因为当我按原样写下程序时,它会稍微出错,这可能是我自己的原因仿函数也会错误地运行。只是猜测。
当我输入:
lower_rank(二等兵,下士)。
Prolog returns 和 true
并等待它,我必须在 true
后面放一个点然后单击 enter 然后才 return ?-
提示。
预期输出为:
return 与 true.
然后 return 到 ?-
提示
作者好像在说这个问题。在第 57 页,他写道“如果目标失败,lower_rank 将不会终止”我已经应用了所有指令,但仿函数仍然不起作用。如何让它发挥作用?
我的序言版本swi-prolog 7.2.0
% John Stobo, problem solving with Prolog, March.1989
% FACTS:
next_degree(private, corporal).
next_degree(corporal, sergeant).
next_degree(sergeant, lieutenant).
next_degree(lieutenant, captain).
next_degree(captain, major).
next_degree(major, "lieutenant colonel").
next_degree("lieutenant colonel", colonel).
next_degree(colonel, "brigadier general").
next_degree("brigadier general", "major general").
next_degree("major general","lieutenant general").
next_degree("lieutenant general", general).
soldier(ryan, private).
soldier(jondoe, corporal).
sooldier(smartson, captain).
% RULES:
lower_rank(R1, R2) :-
next_degree(R1, R2).
lower_rank(R1, R2) :- % this works but if
next_degree(R1, R3), % the result is "true"
lower_rank(R3, R2). % it doesn't end properly
% only if the user types a dot, it ends properly
is_rank_lower(A1,A2) :-
lower_rank(soldier(A1,X), soldier(A2,X)).
% doesn't work because the functors are inserted as
% 'soldier(ryan, _G1471), soldier(jondoe, _G1471))
% not as private, corporal, i.e. they are not evaluated
next_degree/2 似乎是一种奇怪的方法 - 书中建议它是明智的,还是作为不该做的例子?
https://swi-prolog.discourse.group/t/useful-prolog-references/1089
有不错的书这个有效:
% First argument is an atom, hence single quotes in swi-prolog
rank_order(private, 1).
rank_order(corporal, 2).
rank_order(sergeant, 3).
rank_order(lieutenant, 4).
rank_order(captain, 5).
rank_order(major, 6).
rank_order('lieutenant colonel', 7).
rank_order(colonel, 8).
rank_order('brigadier general', 9).
rank_order('major general', 10).
rank_order('lieutenant general', 11).
soldier(ryan, private).
soldier(jondoe, corporal).
% Not mis-spelled as "sooldier"
soldier(smartson, captain).
rank_lower(RankLower, RankUpper) :-
rank_order(RankLower, RankLowerOrder),
rank_order(RankUpper, RankUpperOrder),
RankLowerOrder < RankUpperOrder.
soldier_rank_lower(SoldierLower, SoldierUpper) :-
soldier(SoldierLower, RankLower),
soldier(SoldierUpper, RankUpper),
rank_lower(RankLower, RankUpper).
结果 swi-prolog:
?- rank_lower(private, corporal).
true.
?- soldier_rank_lower(ryan, jondoe).
true.
?- soldier_rank_lower(L, U).
L = ryan,
U = jondoe ;
L = ryan,
U = smartson ;
L = jondoe,
U = smartson ;
false.
第二次尝试:
rank_next(private, corporal).
rank_next(corporal, sergeant).
rank_next(sergeant, lieutenant).
rank_next(lieutenant, captain).
rank_next(captain, major).
rank_next(major, 'lieutenant colonel').
rank_next('lieutenant colonel', colonel).
rank_next(colonel, 'brigadier general').
rank_next('brigadier general', 'major general').
rank_next('major general', 'lieutenant general').
rank_next('lieutenant general', general).
soldier(ryan, private).
soldier(jondoe, corporal).
soldier(smartson, captain).
rank_lower(RankLower, RankUpper) :-
rank_next(RankLower, RankLower1),
% Increase lower to eventually meet with upper
( RankLower1 = RankUpper ;
rank_lower(RankLower1, RankUpper)
).
soldier_rank_lower(SoldierLower, SoldierUpper) :-
soldier(SoldierLower, RankLower),
soldier(SoldierUpper, RankUpper),
% Won't have multiple answers
once(rank_lower(RankLower, RankUpper)).
这使得以下内容具有确定性:
?- soldier_rank_lower(ryan, jondoe).
true.
...同时保持rank_lower/2的一般性,即:
?- findall(L-U, rank_lower(L, U), Pairs), length(Pairs, Len).
Pairs = [private-corporal,private-sergeant,private-lieutenant, ...
Len = 66.