标签: prolog-dif

prolog中的守卫条款?

它们存在吗?他们是如何实施的?

所述coroutining SWI-Prolog的(的谓词freeze,when,dif等)具有的功能警卫.它们如何适合首选的Prolog编程风格?

我是很新的逻辑编程(有序言和共)和事实,即它不是纯粹的声明,并要求即使在非常简单的情况下程序上的考虑有点困惑(见本关于使用问题\==dif).我错过了重要的事吗?

prolog guard-clause prolog-dif prolog-coroutining

9
推荐指数
1
解决办法
932
查看次数

使用手动列表迭代与通过失败递归的优缺点是什么

我一直反对这一点,我无法确定攻击它的方法.以下是处理一些季节事实的两种方法.

我想弄清楚的是,是否使用方法1或方法2,以及每种方法的利弊是什么,特别是大量的事实.

methodone因为事实是可用的,所以似乎很浪费,为什么还要建立一个列表(特别是一个大的列表).如果列表足够大,这也必须有内存含义吗?它没有利用Prolog的自然回溯功能.

methodtwo利用回溯来为我做递归,我猜想会有更多的内存效率,但是通常这样做是不是很好的编程习惯呢?这可以说是更难以理解,可能还有其他副作用吗?

我可以看到的一个问题是每次fail调用时,我们都失去了将任何东西传递回调用谓词的能力,例如.如果是的话methodtwo(SeasonResults),因为我们故意不断地破坏谓词.所以methodtwo需要断言事实来存储状态.

大概(?)方法2会更快,因为它没有(大)列表处理吗?

我可以想象,如果我有一个清单,那么methodone将是要走的路......还是总是如此?在任何情况下都可以将列表声明为事实,methodone然后使用方法二处理它们?完全疯了吗?

但话说回来,我读到断言事实是一项非常"昂贵"的业务,所以列表处理可能是要走的路,即使是大型列表?

有什么想法吗?或者有时候使用一个而不是另一个更好,这取决于(什么)情况?例如.对于内存优化,使用方法2,包括断言事实,以及速度使用方法1?

season(spring).
season(summer).
season(autumn).
season(winter).

 % Season handling
showseason(Season) :-
    atom_length(Season, LenSeason),
    write('Season Length is '), write(LenSeason), nl.

% -------------------------------------------------------------
% Method 1 - Findall facts/iterate through the list and process each
%--------------------------------------------------------------
% Iterate manually through a season list
lenseason([]).
lenseason([Season|MoreSeasons]) :-
    showseason(Season),
    lenseason(MoreSeasons).


% Findall to build a list then iterate until all done
methodone :-
    findall(Season, season(Season), …
Run Code Online (Sandbox Code Playgroud)

prolog prolog-dif prolog-toplevel

8
推荐指数
2
解决办法
2032
查看次数

从列表中删除所有出现的元素

尝试编写一个给出值和列表的过程,它会删除列表中写入的值的所有出现:

delMember(X, [], []) :- !.
delMember(X, [X|Xs], Y) :- !, delMember(X, Xs, Y).
delMember(X, [T|Xs], Y) :- !, delMember(X, Xs, Y2), append([T], Y2, Y).
Run Code Online (Sandbox Code Playgroud)

由于cut此代码无法正确回答如下问题:

delMember(Y, [1,2,3,1,2,3,1,2,3], [1, 2, 1, 2, 1, 2 ]).
Run Code Online (Sandbox Code Playgroud)

如果我删除剪辑:

delMember(X, [], []).
delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y).
delMember(X, [T|Xs], Y) :- delMember(X, Xs, Y2), append([T], Y2, Y).
Run Code Online (Sandbox Code Playgroud)

它在以下查询中失败:

delMember(Y, [1,2,3,1,2,3,1,2,3], [1,2,3,1,2,3,1,2,3]).
Run Code Online (Sandbox Code Playgroud)

(true当正确的答案是时,返回false).

如何使它在两种情况下都能正常工作?

也许我可以X is not T在第三行代码中检查一下,我试过:

delMember(X, [T|Xs], Y) :- …
Run Code Online (Sandbox Code Playgroud)

prolog prolog-dif

8
推荐指数
1
解决办法
2万
查看次数

强制Prolog选择变量的唯一值

好的我是Prolog的新手,请原谅,如果这是微不足道的,但我似乎无法找到一个合适的优雅答案.我试图在learnprolognow.org,练习2.4(填字游戏)上进行练习.

练习提供了以下事实:

   word(astante,  a,s,t,a,n,t,e). 
   word(astoria,  a,s,t,o,r,i,a). 
   word(baratto,  b,a,r,a,t,t,o). 
   word(cobalto,  c,o,b,a,l,t,o). 
   word(pistola,  p,i,s,t,o,l,a). 
   word(statale,  s,t,a,t,a,l,e).
Run Code Online (Sandbox Code Playgroud)

我想出解决每个单词的填字游戏位置的解决方案是这样的:

crossword(V1, V2, V3, H1, H2, H3) :-
   word(V1, V1a, V1bH1b, V1c, V1dH2b, V1e, V1fH3b, V1g), 
   word(V2, V2a, V2bH1d, V2c, V2dH2d, V2e, V2fH3d, V2g), 
   word(V3, V3a, V3bH1f, V3c, V3dH2f, V3e, V3fH3f, V3g), 
   word(H1, H1a, V1bH1b, H1c, V2bH1d, H1e, V3bH1f, H1g), 
   word(H2, H2a, V1dH2b, H2c, V2dH2d, H2e, V3dH2f, H2g), 
   word(H3, H3a, V1fH3b, H3c, V2fH3d, H3e, V3fH3f, H3g).
Run Code Online (Sandbox Code Playgroud)

随着V1aV1g等为每个单词的字符,并且V1bH1b …

prolog crossword prolog-dif

8
推荐指数
1
解决办法
2722
查看次数

Prolog:一个人是自己的兄弟姐妹?

我在理解为什么我的prolog代码根据我的规则的顺序做了一些事情时遇到了一些麻烦.

这是我的数据库:

parent(tom, bob).
parent(tom, liz).
parent(mary, bob).
parent(mary, liz).

male(tom).
male(bob).
female(mary).
female(liz).
Run Code Online (Sandbox Code Playgroud)

以下是规则:

%difference(X, Y) ==> Predicate to check if two people X and Y are not the same person.
difference(X, Y) :- \==(X, Y).
father(X, Y) :- male(X), parent(X, Y), difference(X, Y).
mother(X, Y) :- female(X), parent(X, Y), difference(X, Y).
sibling(X, Y) :-
    difference(X, Y),
    mother(M, X), mother(M, Y),
    father(F, X), father(F, Y).
Run Code Online (Sandbox Code Playgroud)

问题是,当我这样做时,

?- sibling(bob, X).
Run Code Online (Sandbox Code Playgroud)

我明白了

X = bob ;
X = liz ;
false. …
Run Code Online (Sandbox Code Playgroud)

prolog prolog-dif

7
推荐指数
2
解决办法
1191
查看次数

如何验证涉及dif/2约束的交换性?

围绕dif/2约束存在很多炒作,特别是作为对(\ =)/ 2和(\ ==)/ 2的一些非声明性的拯救.这种非声明性通常被描述为非单调性,并给出了非交际性的​​例子.

但是,测试涉及dif/2的测试用例是否可交换的方法是什么.以下是我想要做的元解释:

我进行了交换性测试,我想探究两种变体给出相同的结果:

?- A, B.
-- versus --
?- B, A.
Run Code Online (Sandbox Code Playgroud)

所以通常你可以用(==)/ 2内置谓词检查单调性,如果它归结为检查交换性.由于此谓词遵循实例化变量.

但是,如果您正在测试产生约束的情况,call_with_residue/2是不够的,您还需要具有相等的约束.这可能很棘手,如下例所示:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.23)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam

?- dif(f(X,X),f(a(U,g(T)),a(g(Z),U))), X=a(g(Z),U).
X = a(g(Z), U),
dif(f(a(g(Z), U), U, Z, U, T), f(a(U, g(T)), g(Z), T, g(Z), Z)).

?- X=a(g(Z),U), dif(f(X,X),f(a(U,g(T)),a(g(Z),U))).
X = a(g(Z), U),
dif(f(U, T), f(g(Z), Z)).
Run Code Online (Sandbox Code Playgroud)

任何想法如何进行?

免责声明,它是一个陷阱:
我不认可交换性测试作为一种好的测试方法,在这种方法中你可以将好的和坏的谓词与规范分开.因为通常好的和坏的谓词都可能没有交换性问题.

我正在使用交换性测试作为一种工具来找出有关dif/2约束相等的方法.然后,可以在更传统的测试用例中将此等式用作验证点.

prolog clp prolog-dif

7
推荐指数
1
解决办法
79
查看次数

Prolog:不平等运算符

我正在使用SICStus Prolog并拥有一系列事实:

student('John Henry', 'Maths').
student('Jim Henry', 'Maths').
student('John Alan', 'Maths').
student('Alan Smith', 'Computing').
student('Gary Henry', 'Maths'). 
Run Code Online (Sandbox Code Playgroud)

我想得到两个学生的共同主题,两个学生都不同,所以我得到了:

sharedSubject(S1, S2, Sub) :- S1 \== S2, student(S1, Sub), student(S2, Sub).
Run Code Online (Sandbox Code Playgroud)

但是,当我输入:

sharedSubject('John Henry', F, E).                     
Run Code Online (Sandbox Code Playgroud)

我得到F = 'John Henry'.有人可以指出我出错的地方以及我需要做什么吗?谢谢.

prolog prolog-dif

6
推荐指数
2
解决办法
3857
查看次数

`var(A)`和执行顺序

本页上的练习09 http://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/要求创建一个谓词,将重复的元素打包到子列表中.

一个直截了当的解决方案很简单

pack([], []).
pack([H|T], [I|U]) :-
    split(H, T, I, P),
    pack(P, U).
Run Code Online (Sandbox Code Playgroud)

split split(Head, Tail, HeadGroup, Rest)的定义为

split(A, [], [A], []).
split(A, [B|T], [A], [B|T]) :- A \= B.
split(A, [A|T], [A|U], B) :- split(A, T, U, B).
Run Code Online (Sandbox Code Playgroud)

工作正常,几乎与上述网页上提供的示例解决方案一致.

这个解决方案失败的地方是查询pack(X, [[a], [b, b]])..2个解集之间的对应关系是双射(对于每个Apack(A, B)有一个且只有一个B),所以必须有一个更好的解决方案.

解决它的一种方法是改变评估的顺序,帮助prolog根据参数的类型选择非无限分支,如下所示

pack([], []).
pack(A, B) :-
  ( var(A) ->
    A = [H|T],
    B = [I|U],
    pack(P, U),
    split(H, T, I, P)
  ; A = …
Run Code Online (Sandbox Code Playgroud)

list prolog prolog-dif logical-purity

6
推荐指数
1
解决办法
79
查看次数

Prolog:第一个重复值

我需要在列表中找到第一个重复值.

prep(3,[1,3,5,3,5]). 应该是真的.

prep(5,[1,3,5,3,5]). 应该是假的.

我想检查与当前值和先前列表成员的相等性,直到我找到重复,如果它找到一个它将测试与X的相等但我不知道如何在Prolog中做到这一点!

我感谢任何帮助!谢谢

list prolog prolog-dif

5
推荐指数
2
解决办法
2907
查看次数

如果发生检查

是否存在差异检查?这在这里有效:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.7)

?- set_prolog_flag(occurs_check, true). 
true.

?- dif(X,f(Y)), X = Y.
X = Y.
Run Code Online (Sandbox Code Playgroud)

但以上是不可行的,因为发生检查是一个全局标志,我得到以下信息:

SWI-Prolog console for thread 3

?- X=f(X).
false.
Run Code Online (Sandbox Code Playgroud)

prolog prolog-dif occurs-check

5
推荐指数
1
解决办法
124
查看次数