Prolog 部分词典/记录统一?

Prolog 部分词典/记录统一?,prolog,clojure-core.logic,minikanren,Prolog,Clojure Core.logic,Minikanren,我知道有些序言支持开箱即用的字典式关联数据结构。对于这样做的实现,它们是否支持与另一个实际上并不包含所有键的结构部分统一的概念 例如,在core.logic/miniKanren的语法中: (run* [q] (== {:foo 1 :bar 2} (partial-map :foo q))) 这将返回一个结果,其中q绑定到1 Prolog给这个操作或这个部分结构起了名字吗?一般来说,我们用标准的方法来解决Prolog中基本数据类型选择不当的问题:添加库和使用接口,例如,提供了一个实现基于

我知道有些序言支持开箱即用的字典式关联数据结构。对于这样做的实现,它们是否支持与另一个实际上并不包含所有键的结构部分统一的概念

例如,在core.logic/miniKanren的语法中:

(run* [q]
  (== {:foo 1 :bar 2} (partial-map :foo q)))
这将返回一个结果,其中q绑定到1


Prolog给这个操作或这个部分结构起了名字吗?

一般来说,我们用标准的方法来解决Prolog中基本数据类型选择不当的问题:添加库和使用接口,例如,提供了一个实现基于AVL树的关联数据结构的。(顺便说一句,在函数和逻辑编程中,平衡树比哈希表更常见,因为在树上创建“持久”数据结构比在共享内部结构的FP意义上创建持久的哈希表更容易。)

使用此库的方式如下所示:

?- [library(assoc)].
% library(assoc) compiled into assoc 0.00 sec, 97 clauses
true.

?- empty_assoc(Assoc).
Assoc = t.

?- empty_assoc(Assoc), get_assoc(test, Assoc, V).
false.

?- empty_assoc(Assoc), put_assoc(test, Assoc, foo, Assoc2).
Assoc = t,
Assoc2 = t(test, foo, -, t, t).

?- empty_assoc(Assoc), 
   put_assoc(test, Assoc, foo, Assoc2), 
   get_assoc(test, Assoc2, Value).
Assoc = t,
Assoc2 = t(test, foo, -, t, t),
Value = foo.
association_subset(Left, Right) :-
  forall(gen_assoc(Assoc, Left, Value), get_assoc(Assoc, Right, Value)).
一旦有了这样的接口,就可以在上面定义各种逻辑关系。一旦有了逻辑关系,Prolog的正常统一机制将处理其余的数据类型,不需要对这种或那种数据类型的特殊支持。基于您的需求,我认为您想要的是一个子集关系,除了检查两个关联是否都在另一个关联中,并且它们都具有相同的值。我猜这看起来像这样:

?- [library(assoc)].
% library(assoc) compiled into assoc 0.00 sec, 97 clauses
true.

?- empty_assoc(Assoc).
Assoc = t.

?- empty_assoc(Assoc), get_assoc(test, Assoc, V).
false.

?- empty_assoc(Assoc), put_assoc(test, Assoc, foo, Assoc2).
Assoc = t,
Assoc2 = t(test, foo, -, t, t).

?- empty_assoc(Assoc), 
   put_assoc(test, Assoc, foo, Assoc2), 
   get_assoc(test, Assoc2, Value).
Assoc = t,
Assoc2 = t(test, foo, -, t, t),
Value = foo.
association_subset(Left, Right) :-
  forall(gen_assoc(Assoc, Left, Value), get_assoc(Assoc, Right, Value)).
仅当左关联是右关联的子集时(如上所述),此谓词才为真。我们可以测试它,看看它是否在做我们想要的事情:

simple(Assoc) :- 
  empty_assoc(Empty),
  put_assoc(foo, Empty, foo_test, V1),
  put_assoc(bar, V1, bar_test, Assoc).

complex(Assoc) :-
  simple(Assoc1),
  put_assoc(baz, Assoc1, bazzle, Assoc).

unrelated(Assoc) :-
  empty_assoc(Empty),
  put_assoc(baz, Empty, bazzle, Assoc).

?-简单(X)、复杂(Y)、关联子集(X,Y)。

X=t(foo,foo_test,一些Prolog系统,比如Eclipse,有一个记录符号 当你提前知道地图上可能的关键点时。但是它需要 类型声明。记录表示法也可以在Prolog Decentant中找到 像Erlang这样的语言

想法很简单,你先声明 记录类型(这里发明了一些语法):

现在,您可以在Prolog程序中使用 记录,只需写(这里又发明了一些语法):

在编译类型下,记录将转换为复合记录 然后可以很容易地在正常的统一中使用 根据记录类型对键值对重新排序 声明,然后放下键并仅使用位置。 未使用的位置将替换为注释性变量或 如果记录类型声明也 包括这个

... T(W1, ..., Wn) ...
您的示例将如下所示:

:- rectype myrec{foo, bar}

?- myrec{foo=1,bar=2} = myrec{foo=q}
后一个查询将在内部执行,如下所示:

?- myrec(1,2) = myrec(q,_).
有关Eclipse如何实现的更多详细信息,请参见此处的示例:

对于键集不是静态的动态贴图,可以实现 动态数据结构作为关于SWI Prolog AVL的另一篇文章 树显示。或者向Prolog系统请求特定 数据结构。使用FFI(外部功能接口)实现这些功能 或者访问已经与Prolog系统捆绑在一起的这些。 例如,Eclipse捆绑了一对,请参见“描述”部分 在下面的文章中:


再见

我不太清楚您到底想要什么(您已经删除了散列特性),但也许您更想要特性术语或特性结构

它们受到语言学家的欢迎,并已成为生活的一部分

通过属性变量的帮助实现它们是可能的,但到目前为止,我还没有看到对它们的需求


你也可以用语法统一的方式来模拟它们,这很笨拙,因为你需要用一个单独的参数来表示每个特性(你可以做得稍微好一点,但也会更复杂)。因此,如果您的程序包含n个功能,则功能结构将包含n个不同的参数,其中大多数参数将永远不会被触及。但是,统一将直接按预期工作。

我已经完成了基本搜索,但没有找到任何提供哈希表的Prolog。可能是因为Prolog规则库通常是通过良好的工艺实现的因此,哈希是“内在的”,更像是一个“实现细节”,而不是一个广泛需要的功能。例如,请参阅SWI Prolog作者的文章。不知道这是否仍然让您感兴趣,但这是一个非常简单的可扩展记录的实现,在这里我可以调用
?-attr(a,[foo-1,bar-2]),attr(a,[foo-Q]),然后返回
Q=1
attr(A,[n-V | R]):-memberchk(n-X,A),X=V,attr(A,R)。
attr([u,].
仅此而已。感谢您的解释!我知道我可以从头开始实现它,但我很好奇该模式是否足够常见,以便Prolog对其提供特定支持,以及该支持是否有名称。谢谢!我正在寻找一个类似于此的具体支持示例。是的,哈希方面并不重要,只是一个关联的data结构,其中键顺序对用户不重要。是的,必须显式地枚举每个参数将不太理想-上面提到的Eclipse sugar似乎可以实现您所描述的功能,而不必强迫用户手动完成。
:- rectype myrec{foo, bar}

?- myrec{foo=1,bar=2} = myrec{foo=q}
?- myrec(1,2) = myrec(q,_).