评估Prolog中函子内的函子

发布于 2025-01-21 01:31:55 字数 1977 浏览 0 评论 0原文

我遵循约翰·斯托博(John Stobo)的Prolog 的《解决问题》。我已经研究了第1章(用事实的编程)和第2章(使用规则的编程),现在我在第3章中: em>,我正在练习第3.1节中给出的程序。我已经对该程序进行了一些(不更改主结构)的措施,并添加了名为IS_RANK_LOWER/2的函数(或函数或规则?),但它无法正常工作。

当我输入(或询问Prolog)

IS_Rank_lower(Ryan,Jondoe)时。

输出是

错误的。

预期输出:正确。

因为瑞安(Ryan)是私人,而乔多(Jondoe)是下士,私人的排名低于下士。

解释在代码中。

问题#1 :如何使我自己的函数is_lower_rank按预期工作?

问题#2 :这个问题可能与这本书有关,因为当我完全按原样写下程序时,它的工作方式有些错误,这可能会导致我自己的函数错误地运行。只是一个猜测。

当我输入时:

lower_rank(私人,下士)。

prolog返回true并等待它,我必须在true之后放一个点,然后单击Enter,它仅返回? - 提示。

预期输出是:

返回true。,然后返回? -提示提示

作者似乎谈论了这个问题。在第57页中,他写道:“如果目标应该失败,Lower_rank将不会终止”,我已经应用了所有说明,但函子仍然不起作用。如何使其工作?

我的Prolog版本 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

I follow the book Problem solving with Prolog by John Stobo. I've studied the Chapter 1 (Programming with Facts) and Chapter 2 (Programming with Rules) Now I am at Chapter 3: Recursion in Rules and I'm practicing the program given in the Section 3.1. I've elobarated the program a bit (without changing the main structure) and added my own functor (or function or rule ?) named is_rank_lower/2 but it doesn't work as expected.

When I enter (or ask Prolog)

is_rank_lower(ryan, jondoe).

the output is

false.

the expected output: true.

Because ryan is a private and jondoe is a corporal and private is lower in rank than corporal.

The explanations are in the code.

Question #1: How to make my own functor is_lower_rank work as expected?

Question #2: This question might be related to the book because when I write down the program exactly as it is, it works slightly wrongly and that might be causing my own functor to function wrongly, too. Just a guess.

When I enter:

lower_rank(private, corporal).

Prolog returns with true and waits at it, I have to put a dot after the true and click enter only then does it return to the ?- prompt.

The expected output is:

return with true. then return to the ?- prompt

The author seems to talk about this problem. In page 57 he writes "lower_rank would not terminae if the goal ought to fail" I've applied all the instructions but the functor still doesn't work. How to make it work?

My prolog version 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

所谓喜欢 2025-01-28 01:31:55

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.

That next_degree/2 seems like a bizarre method - is the book suggesting it as sensible, or as an example of what not to do?

There are decent books at https://swi-prolog.discourse.group/t/useful-prolog-references/1089

This works:

% 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).

Results in 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.

2nd attempt:

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)).

This makes the following deterministic:

?- soldier_rank_lower(ryan, jondoe).
true.

... whilst keeping the generality of rank_lower/2, i.e.:

?- findall(L-U, rank_lower(L, U), Pairs), length(Pairs, Len).
Pairs = [private-corporal,private-sergeant,private-lieutenant, ...
Len = 66.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文