Javascript似乎成为其他编程语言的实现语言.文章 轻量级编译(C)LP到JavaScript.ICLP 2012 引起了我的注意.
在Web上用Javascript编写的Prolog系统有很多概念验证原型.
什么是当前的,积极维护的,最好是用Javascript编写的符合ISO标准的Prolog系统?
给出两个变量列表,ISO Prolog中最紧凑和规范的方法是什么来确定两者的结合?也就是说,我们想要(元逻辑)谓词的定义
varset_union(VarSet1, VarSet2, Union)
以及列表清单
varset_union(VarSets, Union)
其中Union是给定VarSets 的唯一变量列表.
ISO-Prolog提供sort/2并keysort/2依赖于通常称为"标准期限订单"的期限订单(7.2).对具有不同顺序的列表进行排序的常用方法是以某种方式将该列表的每个元素映射El到对列表,XKey-El然后对该列表进行排序,最后将密钥投射出去.作为一个例子,考虑如何keysort/2表达sort/2(参见实施说明).
在许多情况下,这种方法比使用通用实现特定排序谓词快得多,后者依赖于用户定义的顺序作为SWI predsort(C_3, List, SortedList)
或SICStus' samsort(O_2, List, SortedList).
我的问题归结为:
是否存在使用
predsort/3resp 进行排序的情况.samsort/3不能被一些映射,sort/2-ing和投射取代?1
并且为了清楚起见,更好地坚持有限的基础术语.因为,无限的地面术语不具有完整的词典顺序,因为它需要作为有限情况的扩展; 而且,目前尚不清楚如何将变量与两个不同变量的情况进行比较,如果符合ISO/IEC 13211-1:1995的7.2.1,那将是如何实现的:
7.2.1变量
如果
X和Y是不相同的变量,则
Xterm_precedesY应依赖于实现,
除了在创建排序列表(
7.1.6.5,8.10.3.1 j)期间,排序应保持不变.
因此,目前尚不清楚是否predsort/3仍有资格作为排序列表的创建.很清楚的是,在 sort/2和期间,顺序保持不变keysort/2.
1感谢@WillNess,这个预测应该至少包括reverse/2- 或任何线性变换.这也意味着可以实现具有重复和独特结果的结果(类似于实现的方式keysort/2).
ISO Prolog中用于测试不同变量列表的最紧凑和规范的方法是什么?我们称之为元逻辑谓词is_varset/1.
因此,如果它的参数是一个完全不同的变量列表,它应该会成功.请注意,列表[]的末尾始终包含a .如果变量在最后,我们将其称为部分列表(因此不是列表).如果一个非变量项作为既不是[]也不是变量的后缀出现,那么这既不是部分列表也不是列表.
术语既不是部分列表也不是列表的一个值得注意的特殊情况是无限列表.它们包含至少两个相同的后缀,实际上它们拥有无限的后缀.无限列表超出了标准的范围 - 所有创建它们的尝试都会导致STO统一,其结果是未定义的.尽管如此,有些系统支持它们,因此理想情况下,这些无限列表is_varset/1应该有限地失败.
?- is_varset([A|nonlist]).
false.
?- is_varset([A,B]), is_varset([B,A]).
true.
?- is_varset([A,B,A]).
false.
?- is_varset([A,f(B)]).
false.
?- is_varset([A|_]).
false.
?- L = [_|L], is_varset(L).  % may loop, should rather terminate
false.
如果您定期编写Prolog程序,您可能拥有自己依赖的谓词库.一些Prolog系统带有丰富的预定义谓词,有些则没有.有些系统有库,但它们与其他系统大多不兼容.此外,许多现有的库包含许多很少需要的谓词.但是,有一些谓词"应该"始终存在.然后,有一些进展,因为十一月发生这样和Cor.2(草案).为什么不在这里呢?
那么你最喜欢的谓词是什么?这是谓词,在ISO核心中没有定义.
首先:between/3,member/2,length/2,dif/2,maplist/2,...
对于DCG中:seq//1,iseq//1,... //0.
好的,我知道这是一个非常普遍的问题,并且已经写了一些关于这个主题的论文,但我觉得这些出版物涵盖了非常基本的材料,我正在寻找更先进的东西来改善风格和效率.这就是我的论文:
这些主题涵盖的示例主题包括:尾递归和差异列表,正确使用索引,正确使用剪切,避免断言和缩回,避免CONSing,代码格式化指南(缩进,if-then-elses等),命名约定,代码记录,参数顺序,测试.
您将从Prolog的个人经历中添加什么?是否有适用于CLP编程的特殊风格指南?你知道一些常见的效率问题,知道如何处理它们吗?
更新:
这里有一些有趣的(但仍然太基础和太笼统)点:Lifeware团队的Prolog编程指南
为了突出整个问题,我想问一下"Prolog的编码指南"(Covington等人):
据我们所知,Prolog的一套连贯且相当完整的编码指南从未发布过.此外,当我们查看已发布的Prolog程序的语料库时,我们看不到事实上的标准出现.这一明显遗漏背后的最重要原因是,由于缺乏全面的语言标准,小型Prolog社区进一步分散为以个体Prolog系统为中心的子社区,其中没有一个具有支配地位.
在较旧的教科书1中,经常遇到如下的操作员声明:
?- op(1200,fx,(:-)).
              ^  ^
过去,这些圆括号是必要的.但今天,他们不再需要了:
| ?- writeq(op(1200,fx,(:-))).     
op(1200,fx,:-)
为什么不再需要它们?标准如何应对这种情况?
1 p.97 6. MU-Prolog 3.2db参考手册的标准操作员声明,出现在Prolog的否定和控制中,Lee Naish,LNCS 238,Springer-Verlag 1985.
当使用字符(字符列表,因此长度为一的原子)来表示文本时,我们可以使用以下选项将它们写入术语中:
"First,"双引号列表表示法 (6.3.7) 是最有效的一种,至少需要n+2 个字符。double_quotes但只有当 Prolog 标志设置为chars时才能读回。
['N',e,x,t,',']出现至少2n+1 个字符的列表符号。虽然它很好并且相对紧凑,但它意味着在写入其他数据时也会使用运算符,因为它是通过 启用的ignore_ops(false),并且这需要在读取时出现相同的运算符,这使得它非常脆弱。
'.'('L','.'(a,'.'(s,'.'(t,'.'(',',[])))))使用函数形式的规范表示法也适用于需要至少7n+2 个字符的列表。这是很多,但对于互操作性(包括与同一系统的互操作性)来说这是最好的,因为它既不依赖于标志double_quotes也不依赖于各种运算符声明。
以规范表示法写入字符可以在常量空间中完成。但对于阅读来说,情况就有点棘手了。毕竟,以 开头的序列'.'(a,也可以指代术语'.'(a,Further,b)。因此,天真的阅读必须等待(并使用空间),直到读入整个字符列表。另一方面,这似乎是一个安全的赌注,'.'(a,将是一个列表构造函数'.'(a,Further)。换句话说,
如何使用规范符号来读取术语,并使用恒定的辅助空间来读取其中的字符?
如果有帮助,请考虑条款sampleterm/1。因此,请考虑阅读以规范形式编写的所有此类术语。并且,如果您愿意,可以将其表述为 DCG。
sampleterm([]).
sampleterm(a).
sampleterm(b).
sampleterm('.'(E,Es)) :- % the real list constructor 
   sampleterm(E),
   sampleterm(Es).
sampleterm('.'(E,F,G)) :- % no list constructor
   sampleterm(E),
   sampleterm(F),
   sampleterm(G).
如果这种节省空间的读取是可能的,那么支持诸如 Scryer 和 Trealla 之类的紧凑内部字符表示的系统甚至可以更进一步。
啊,以免我忘记我尝试过的:read/1确实如此,但目前并不理想。
prolog中的管道运算符返回一个或多个原子头和尾部列表.
?- [a,b,c] = [a,b|[c]].
true.
在单个匹配中嵌套多个管道可以这样做:
?- [a,b,c] = [a|[b|[c]]].
true.
该声明[a|b|c]对a,b和c的推断是什么?
编辑
到目前为止,我所能推断的是:
?- [a,b,c] = [a|b|c].
false.
我对找到答案的任何技术更感兴趣,而不是回答这个边缘无用的问题.
EDIT2
 
我显然不太熟悉prolog,一个简单的任务回答了我的问题......
?- R = [a|b|c].
R = [a| (b'|'c)].
究竟发生了(b'|'c)什么?
iso-prolog ×10
prolog ×10
compilation ×1
cons ×1
dcg ×1
iso ×1
javascript ×1
operators ×1
pipe ×1
sorting ×1
standards ×1
syntax ×1
transpiler ×1