在Haskell中,有一种称为"as"-operator的语言特性(有时称为别名).这个想法如下:假设您有一个函数,例如将列表作为输入并希望返回所有尾部,您可以将其实现为:
tails a@(_:xs) = a : tails xs
tails [] = [[]]
Run Code Online (Sandbox Code Playgroud)
的@,你必须把全部参数的引用,以及对参数的结构的某些部分的引用保证.这是智能性能(它更像是一个性能破解,因为重建一个数组(x:xs))在第一行的主体中,如果没有被编译器优化,将导致分配一个新对象,修改字段等.见这里欲获得更多信息.
我想知道Prolog是否有相同的东西:例如,如果你想在Prolog中实现尾部,可以通过以下方式完成:
tails([H|T],[[H|T]|TA]) :-
tails(T,TA).
tails([],[[]]).
Run Code Online (Sandbox Code Playgroud)
但如果有一个"as"运算符,它可能会更有效:
tails(L@[_|T],[L|TA]) :- %This does not compile
tails(T,TA).
tails([],[[]]).
Run Code Online (Sandbox Code Playgroud)
有没有这样的结构或语言扩展?
这是我的SWI-Prolog计划的概述:
:- use_module(library(clpfd)).
consec1(L) :-
L=[L1,L2,L3,L4,L5,L6,L7,L8,L9],
L ins 1..9,
...,
abs(L5-L4)#=1,
all_different(L),
labeling([],L)
Run Code Online (Sandbox Code Playgroud)
abs(L5-L4)#=1让L5和L4彼此相邻.如果我想让三个数字彼此相邻,例如L3,L4并且L5,我怎么能使用具体约束来做到这一点?
例如L3=4,L5=5,L4=6或L4=7,L5=8,L3=9
我在SICStus Prolog 4.3.2中观察到的令人困惑的性能差异已经完全消失,最近发布的SICStus Prolog 4.3.3.奖励!
我更新了下面的"运行时"表,包括SICStus Prolog 4.3.3.亮点包括:
(is)/2是快达10倍比以前.val_of/2也加速了,差不多快了2倍!MEGO ;-)
当回答 "这个问题在序言语言大小程序 " SO-用户@ThanosTintinidis提出了一个显着简单的方法1介绍初学者获得的length/2:
[...]另请注意,
E仅需要实例化因为是要评估表达式.你可以写这样的东西:size([], 0). size([_|Xs], 1+E) :- size(Xs, E).如果你打电话给它:
?- size([_,_], E). E = 1+(1+0).好玩,不是吗?您可能想要评估最后一次
E,即通话?- size([1,2], E), N is E.[...]
好玩吗? 好玩! 未来将进行一些有趣的实验:
左倾与右倾树木
list_sizL([], 0). % left-leaning list_sizL([_|Es], N+1) :- list_sizL(Es,N). list_sizR([], 0). % …
我想访问列表排列并将其作为参数传递给其他函数.
这是排列代码:
takeout(X,[X|R],R).
takeout(X,[F|R],[F|S]) :-
takeout(X,R,S),
write(S).
perm([X|Y],Z) :-
perm(Y,W),
takeout(X,Z,W).
perm([],[]).
Run Code Online (Sandbox Code Playgroud) 我正在努力克服throw/1的精确语义,而没有ISO Prolog中合适的catch/3.我正在阅读ISO Prolog规范,在我看来,执行将以无限递归结束.
(请注意,您必须能够访问ISO Prolog标准才能解释此问题).
步骤1.假设我们调用throw(未知),并且堆栈上没有catch/3.
步骤2.它将在7.8.10.1 c)结束,说它将是一个系统错误(7.12.2 j).
第3步.这是在其他地方用于其他地方的同一种配方,所以我认为它应该以相同的方式解释.因此7.12.1适用,并且当前目标(throw/1)将被throw替换(error(system_error,Imp_def)).
步骤4.执行此目标将在堆栈上找不到活动的"catch".因此,它应该尝试相同的步骤,继续步骤2,依此类推=>无限递归.
你可能会说未被捕获的"throw"转换为system_error是"最终的"并且不会像其他错误一样进一步处理,并且它可能必须如此,以避免我描述的问题,但我的问题是,标准在哪里涵盖?
其他一些注释,为了完整性:
7.12.2中的注4也提到了在这种情况下出现系统错误的可能性.我认为那里使用的公式("......没有活跃的目标捕获/ 3")在另一个方面引入了一些混淆,因为它应该符合条件,即捕手必须与错误术语统一(B ).
将未捕获的throw-s转换为系统错误背后的想法是什么?它看起来可能存在,使Prolog处理器的顶级生活"更容易",因此它只能收到一个可预测的错误?对我而言,这带来的问题多于好处 - 错误的真正原因因此消失 - 任何意见或评论?
形式语义(附件A)似乎也以某种方式与此斗争,尽管我没有详细研究它.在A.2.5,它提到,"...然而,在正式规范有在根捕手...",并且涉及它,例如,向的findall/3的执行.那么正式的规范与正文有何不同?
我想在SICStus Prolog中看到谓词目标内的执行时间.
示例:
pred :-
goal1,
time,
goal2,
time.
go :-
call(pred).
time_go :-
go,
times(go).
Run Code Online (Sandbox Code Playgroud)
预期结果:
?- time_go.
times_go = 1000ms ,
times_go_goal1 = 500ms,
times_go_goal2 = 500ms
Run Code Online (Sandbox Code Playgroud)
怎么做 ?
我尝试过time_out(:Goal, +Time, -Result),library(timeout)但是我收到了这个错误:
| ?- time_out(char_code(a,N), T, Res).
! Instantiation error in argument 2 of user:time_out/3
! goal: time_out(user:char_code(a,_193),_179,_181)
| ?- time_out(char_code(a,N), 1000, Res).
N = 97,
Res = success ? ; % Res=timeout in other example
Run Code Online (Sandbox Code Playgroud) prolog ×5
alias ×1
clpfd ×1
constraints ×1
haskell ×1
iso-prolog ×1
list ×1
performance ×1
permutation ×1
prolog-dif ×1
swi-prolog ×1