有什么设计启发式的人必须掌握好写Prolog?我听说需要一名经验丰富的程序员大约两年才能熟练掌握Prolog.有效地使用递归是其中的一部分,但这似乎是一个相对较小的障碍.究竟是什么给程序员带来了这么多麻烦?我应该在示例代码中寻找什么来判断其质量?
我知道这一点var/1,nonvar/1并且!/0是不纯的基元,但它们的使用是否会使每个使用它们的程序都不纯净?
我写了下面的谓词plus/3,表现得好像是纯粹的,或者至少是我声称的那样.谓词是示范性的,不是为了提高效率.
% nat(X) is true if X is a natural number
nat(0).
nat(X):- nonvar(X), !, X > 0.
nat(X):- nat(X1), X is X1 + 1.
% plus(A, B, C) is true if A,B and C are natural numbers and A+B=C
plus(A, B, C):-
nat(A),
(nonvar(C), C < A, !, false ; true),
plus_(B, A, C).
plus_(A, B, C):-
nat(A),
(nonvar(C), C < A, !, false ; true),
C1 is …Run Code Online (Sandbox Code Playgroud) 首先,我已经阅读了有关Prolog削减使用的所有其他帖子,并且肯定会看到与使用它们相关的问题.但是,对我来说仍然有些不清楚,我想一劳永逸地解决这个问题.
在下面的简单示例中,我们递归遍历列表并检查每个第2个元素是否等于1.执行此操作时,递归过程可能会在以下任一基本情况中结束:空列表或具有单个元素的列表仍然存在.
base([]).
base([_]).
base([_,H|T]) :- H =:= 1, base(T).
Run Code Online (Sandbox Code Playgroud)
执行时:
?- time(base([1])).
% 0 inferences, 0.000 CPU in 0.000 seconds (74% CPU, 0 Lips)
true ;
% 2 inferences, 0.000 CPU in 0.000 seconds (83% CPU, 99502 Lips)
false.
?- time(base([3,1,3])).
% 2 inferences, 0.000 CPU in 0.000 seconds (79% CPU, 304044 Lips)
true ;
% 2 inferences, 0.000 CPU in 0.000 seconds (84% CPU, 122632 Lips)
false.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我总是在第二个基本情况下使用显式切割运算符(即代表列表中剩下一个元素的那个),如下所示,以取消冗余选择点.
base([]).
base([_]) :- !.
base([_,H|T]) :- H =:= 1, base(T). …Run Code Online (Sandbox Code Playgroud) deterministic prolog non-deterministic prolog-cut logical-purity
这是我的课堂问题之一.
我能够用if-else创建我自己的Prolog程序,但我被告知我的程序并不是完全声明的,因为它是Prolog中最基本的原则之一.
这是我的代码
%start with :- go.
is_spicy :-
write('Do you want spicy? (yes/no)'),
read(Preference),
( Preference == yes -> recommend("Curry"); recommend("Kurma") ).
is_fry :-
write('Do you want fry food? (yes/no)'),
read(Preference),
( Preference == yes -> recommend("StirFry"); recommend("Chicken") ).
is_chili :-
write('Do you want chili? (yes/no)'),
read(Preference),
( Preference == yes -> recommend("Sambal"); recommend("Singgang") ).
recommend(Food) :- write('We recommend you '), write(Food).
go :-
write('Which food type do you prefer? (indian, chinese, malay): '),
read(FoodType),
(
FoodType == indian …Run Code Online (Sandbox Code Playgroud) 本页上的练习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个解集之间的对应关系是双射(对于每个A在pack(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) 这个问题
我有一个与逻辑纯度有关的问题.
这个节目是纯粹的吗?
when(ground(X), X > 2).
Run Code Online (Sandbox Code Playgroud)
关于上下文的一些[ir]相关细节
我正在尝试编写具有良好终止属性的纯谓词.例如,我想编写一个list_length/2描述列表与其长度之间关系的谓词.我想实现与内置谓词相同的终止行为length/2.
我的问题试图找出以下谓词是否纯粹:
list_length([], 0).
list_length([_|Tail], N):-
when(ground(N), (N > 0, N1 is N - 1)),
when(ground(N1), N is N1 + 1),
list_length(Tail, N1).
Run Code Online (Sandbox Code Playgroud)
我可以用clpfd实现我的目标......
:- use_module(library(clpfd)).
:- set_prolog_flag(clpfd_monotonic, true).
list_length([], 0).
list_length([_|Tail], N):-
?(N) #> 0,
?(N1) #= ?(N) - 1,
list_length(Tail, N1).
Run Code Online (Sandbox Code Playgroud)
......或者我可以使用var/1,nonvar/1并且!/0,后来是很难证明谓词是纯粹的.
list_length([],0).
list_length([_|Tail], N):-
nonvar(N), !,
N > 0,
N1 is N - 1,
list_length(Tail, …Run Code Online (Sandbox Code Playgroud) 问题:是否有一些地方可以查看一些程序?我正在谈论rosetta代码风格,但我去了那里,看到几乎每个程序都用非纯语法语法解决(使用剪切,使用IS,那种类型的东西),由于我的学习要求,这对我没有帮助.
那么有没有一半的好消息来源?我正在谈论小型程序,比如在一个固定的地方插入一个元素等等,当我能够检查我是否正确的做事时,我发现我学到了更多的东西
大家好,我正在学习prolog,我现在已经找到了prolog!这让我在两次快速阅读中比在2个月的课堂上学习更多的prolog.我甚至正确地解决了一些练习,这让我很惊讶.所以我想保持这个轨道(我已经做了很多练习直到第五章,我找到了几个githubs,我可以检查我是否接近解决方案,如果我的解决方案错过了案例,等等)谢谢提前
值得一提的是,我正在谈论这样的事情,如果它可以超过3个例子更好但是这类问题
http://www.irisa.fr/prive/ridoux/ICLP91/node7.html#SECTION00031000000000000000
计算机功能/过程/谓词必须满足哪些要求才能被视为“单调”?
Let A be some thing ,
Let B be some thing ,
Let R be a monotonic relationship between A and B ,
Let R_ be a non-monotonic relationship between A and B ,
Let R become false if R_ is true ,
Let R_ become true if R is false ,
Let C be a constraint in consideration of R ,
Let C become false if R_ is true ,
Let D be the collection of constraints C …Run Code Online (Sandbox Code Playgroud) 以下 Prolog 程序定义了一个谓词,deleted/3用于从第二个参数中传递的列表中删除第一个参数中传递的所有出现的项目,并生成第三个参数中传递的列表:
deleted(_, [], []).\ndeleted(X, [X|Y], Z) :-\n deleted(X, Y, Z).\ndeleted(U, [V|W], [V|X]) :-\n deleted(U, W, X),\n U \\= V.\nRun Code Online (Sandbox Code Playgroud)\n?- deleted(a, [a, b, a], [b]).\n true\n; false.\nRun Code Online (Sandbox Code Playgroud)\n?- deleted(X, [a, b, a], [b]).\n X = a\n; false.\nRun Code Online (Sandbox Code Playgroud)\n?- deleted(a, [a, b, a], Z).\n Z = [b]\n; false.\nRun Code Online (Sandbox Code Playgroud)\n?- deleted(X, [a, b, a], Z).\n X = …Run Code Online (Sandbox Code Playgroud) same_length/2鉴于as的频繁纯定义
same_length([],[]).
same_length([_|As], [_|Bs]) :-
same_length(As, Bs).
?- same_length(L, [_|L]).
loops.
Run Code Online (Sandbox Code Playgroud)
是否有一个纯粹的定义不会在这种情况下循环?类似于纯(但效率较低)版本的append/3称为append2u/3.
我知道如何手动捕获此类情况等var/1,但理想情况下,需要一个与原始定义一样纯粹的版本。或者至少它应该很简单。
我尝试过的是上面的定义。
似乎有必要澄清一下:
请注意,某些查询本质上不能终止。考虑到:
?- same_length(Ls, Ks).
Ls = [], Ks = []
; Ls = [_A], Ks = [_B]
; Ls = [_A,_B], Ks = [_C,_D]
; Ls = [_A,_B,_C], Ks = [_D,_E,_F]
; Ls = [_A,_B,_C,_D], Ks = [_E,_F,_G,_H]
; ... .
Run Code Online (Sandbox Code Playgroud)
没有其他方法可以使用语法答案替换的语言来枚举所有解决方案。
但对于给定的查询,实现仍然可能终止。
logical-purity ×10
prolog ×10
logic ×2
declarative ×1
list ×1
prolog-cut ×1
prolog-dif ×1
sequence ×1
termination ×1