在阅读SICP时,我遇到了逻辑编程第4.4章.然后我开始研究Prolog编程语言并尝试理解Prolog中的一些简单的任务.我发现Prolog似乎在数值计算方面遇到麻烦.
这是标准Prolog中的阶乘计算:
f(0, 1).
f(A, B) :- A > 0, C is A-1, f(C, D), B is A*D.
Run Code Online (Sandbox Code Playgroud)
我发现的问题是我需要引入两个辅助变量(C
和D
),一个新的语法(is
),并且问题是不可逆的(即,f(5,X)
按预期工作,但f(X,120)
不能).
天真的,我希望至少C is A-1, f(C, D)
可以用上面的东西代替f(A-1,D)
,但即使这样也行不通.
我的问题是:为什么我需要在数值计算中做这些额外的"东西",而不是在其他查询中呢?
我明白(并且SICP非常清楚),一般来说,"做什么"的信息不足以回答"如何做"的问题.因此,(至少一些)数学问题的陈述性知识不足以真正解决这些问题.但这引出了下一个问题:Prolog中这些额外的"东西"如何帮助我将制定局限于那些"做什么"足以回答"如何做"的问题?
我想知道Prolog在C或C++中的实现方式如何.我主要感兴趣的是将它构建为C或C++库,尽管解释器应用程序也可以.我有兴趣阅读它的内部,即查询执行,即查找解决方案和相关的数据类型.如果您向我推荐任何有关主题的阅读材料或任何直接建议/建议,我将很高兴.读数可能适用于其他OOP语言或一般OOP.最耗尽的材料将解决这个问题.
我是Prolog的新手.我只是想在Windows Vista上从Prolog获得一些输出.
我已经下载并安装了Prolog 5.1; 我在安装时选择了.pro文件扩展名(不要与Perl文件混淆).
我创建了一个名为的文件test.pro
.在这个文件中我放了以下内容:
inside(tom).
?-inside(tom).
Run Code Online (Sandbox Code Playgroud)
我双击该文件并弹出一个命令行界面.在这个界面上(在一堆通用的Prolog版本/版权信息之后),唯一的输出是:
1 ?-
Run Code Online (Sandbox Code Playgroud)
好的,首先,我没想到它会问一个问题; 我希望它能回答一个问题("是"的问题).
无论如何,我试图用以下内容回复查询:
在命令行中我重新插入'inside(tom).',所以整行看起来像:
1 ?- inside(tom).
Run Code Online (Sandbox Code Playgroud)
我按下Enter并收到一条错误消息:
ERROR: toplevel: Undefined procedure: inside/1 (DWIM could not correct goal)
Run Code Online (Sandbox Code Playgroud) 我试图在prolog中写一个程序,如果L1 = [1,2,3]和L2 = [4,5,6]则L3 = [1,4,2,5,3,6]
所以 shuffle([1,2,3],[4,5,6],[1,4,2,5,3,6])
到目前为止我有这个:
shuffle([X],[Y],[X,Y]).
shuffle([X|Xs],[Y|Ys],_) :- shuffle(Xs,Ys,Z), shuffle(X,Y,Z).
Run Code Online (Sandbox Code Playgroud)
这是我编写prolog代码的第一次尝试,所以我仍然试图围绕语法,规则和一切.
我理解逻辑,我只是不确定如何实现它所以任何帮助将不胜感激!
谢谢!
编辑:我已经弄清楚了.如果有人感兴趣,这是解决方案:
shuffle([X],[Y],[X,Y]).
shuffle([X|Xs],[Y|Ys],[Z1,Z2|Zs]) :- shuffle([X],[Y],[Z1,Z2]),shuffle(Xs,Ys,Zs).
Run Code Online (Sandbox Code Playgroud) 我正在研究一个小的prolog应用程序,以解决摩天大楼和栅栏难题.
一个未解决的难题:
一个解决的难题:
当我通过程序已经解决的谜题时,它很快,几乎是即时的,为我验证它.当我通过程序真正的小谜题(例如,2x2,当然有修改的规则),找到解决方案也很快.
问题在于计算具有6x6"原生"大小的谜题.我让它在中止前运行了5个小时左右.太多时间了.
我发现花费时间最长的部分是"围栏",而不是"摩天大楼".分别运行"摩天大楼"可以快速解决问题.
这是我的栅栏算法:
Max
,Max
- > 1(Max
是路径中最后一个顶点的数字.计算通过maximum/2
)Max
等于(BoardWidth + 1)^2 - NumberOfZeros
(BoardWidth+1
是沿边缘的顶点数,并NumberOfZeros
通过计算count/4
).nvalue(Vertices, Max + 1)
以确保不同值的数量Vertices
是Max
(即顶点的路径数)加1
(零个值)3
并强制路径开始和结束,以提高效率我该怎么做才能提高效率?代码包含在下面以供参考.
skyscrapersinfences.pro
:-use_module(library(clpfd)).
:-use_module(library(lists)).
:-ensure_loaded('utils.pro').
:-ensure_loaded('s1.pro').
print_row([]).
print_row([Head|Tail]) :-
write(Head), write(' '),
print_row(Tail).
print_board(Board, BoardWidth) :-
print_board(Board, BoardWidth, …
Run Code Online (Sandbox Code Playgroud) prolog path-finding constraint-programming sicstus-prolog clpfd
我正在prolog中编写一个程序来计算列表中数字的出现次数
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([_|T],X,Z):- count(T,X,Z).
Run Code Online (Sandbox Code Playgroud)
这是输出
?- count([2,23,3,45,23,44,-20],X,Y).
X = 2,
Y = 1 ;
X = 23,
Y = 2 ;
X = 23,
Y = 1 ;
X = 3,
Y = 1 ;
X = 45,
Y = 1 ;
X = 23,
Y = 1 ;
X = 44,
Y = 1 ;
X = -20,
Y = 1 ;
false.
Run Code Online (Sandbox Code Playgroud)
它数次数相同
任何帮助表示赞赏
据我所知,一些Prologs支持类似字典的关联数据结构.对于这样做的实现,它们是否支持部分统一的概念与另一个实际上不包含所有键的结构?
例如,在core.logic/miniKanren的语法中:
(run* [q]
(== {:foo 1 :bar 2} (partial-map :foo q)))
Run Code Online (Sandbox Code Playgroud)
这将返回单个结果,其中q绑定为1.
Prologs会给这个操作或这个部分结构起一个名字吗?
我在Haskell中有一个列表理解,我想翻译成Prolog.
列表理解的重点是旋转4乘4格:
rotate :: [Int] -> [Int]
rotate grid = [ grid !! (a + 4 * b) | a <- [0..3], b <- [0..3] ]
Run Code Online (Sandbox Code Playgroud)
现在在Prolog中,我翻译成这样:
rotateGrid([T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15],
[T0,T4,T8,T12,T1,T5,T9,T13,T2,T6,T10,T14,T3,T7,T11,T15]).
Run Code Online (Sandbox Code Playgroud)
我们可以做得更好吗?
作为Prolog新手,我尝试定义一个谓词filter_min/2
,该谓词采用两个列表来确定第二个列表是否与第一个列表相同,但是删除了所有出现的最小值.
具有预期结果的示例查询:
?- filter_min([3,2,7,8], N).
N = [3,7,8].
?- filter_min([3,2,7,8], [3,7,8]).
true.
Run Code Online (Sandbox Code Playgroud)
我试过但总是得到相同的结果:false
.我不知道问题是什么.我需要帮助!
这是我的代码:
filter_min(X,Y) :-
X == [],
write("ERROR: List parameter is empty!"),
!;
min_list(X,Z),
filter(X,Y,Z).
filter([],[],0).
filter([H1|T1],[H2|T2],Z) :-
\+ number(H1),
write("ERROR: List parameter contains a non-number element"),
!;
H1 \= Z -> H2 is H1, filter(T1,T2,Z);
filter(T1,T2,Z).
Run Code Online (Sandbox Code Playgroud) 到目前为止,我一直坚持 Prolog程序意味着:
如果对于一个查询
Q
,有一个subtermS
,使得存在一个术语T
,使?- S=T, Q.
成功虽然?- Q, S=T.
失败,然后通过调用一个谓词Q
是不踏实.
直觉上,我因此坚定地表示我们不能使用实例化来"欺骗"谓词来提供解决方案,否则这些解决方案不仅不会被给予,而是被拒绝.注意非终止程序的区别!
特别是,至少在我看来,逻辑纯度总是意味着坚定不移.
例子.为了更好地理解坚定性的概念,考虑这个属性的几乎经典的反例,在将高级学生引入Prolog的操作方面时经常引用,使用两个整数之间关系的错误定义及其最大值:
integer_integer_maximum(X, Y, Y) :- Y >= X, !. integer_integer_maximum(X, _, X).
这个中的一个明显错误 - 我们应该说" 摇摆不定 " - 定义当然是以下查询错误地成功:
?- M = 0, integer_integer_maximum(0, 1, M). M = 0. % wrong!
而交换目标产生了正确的答案:
?- integer_integer_maximum(0, 1, M), M = 0. false.
这个问题的一个很好的解决方案是依靠 …