我们可以从Prolog代码中创建一个事实吗?

时间:2016-10-01 23:13:18

标签: list prolog

我的目标是打破给定的列表列表,使我能够以相同的名称访问各个列表。我有以下清单: -

mylist([[1,2],[2,3],[3,4],[4,6]]).

我想将列表分成[1,2],[2,3],[3,4],[4,6],以便我可以单独访问项目(如[1,2])。

为此,我可以从分隔的列表元素中创建新事实吗?我能够将元素分成单独的列表。但是,我想将这些个人名单转化为事实。如: -

mylist([[1,2],[2,3],[3,4],[4,6]]).

应该成为以下内容: -

node([1,2]).
node([2,3]).
node([3,4]).
node([4,6]).

然后我应该能够使用" node"来访问每个列表。

2 个答案:

答案 0 :(得分:1)

另一个答案很好(尤其是forall解决方案),但如果您在编译时知道列表并希望将node/1个事实添加到数据库,那么您可以执行此操作在编译时。

此代码简化自this page最底层的示例:

在你的文件中(我将其命名为nodes.pl):

term_expansion(nodes_list(NL), Nodes) :-
        maplist(to_node, NL, Nodes).

to_node(X, node(X)).

nodes_list([[1,2],[2,3],[3,4],[4,6]]).

当我查阅该文件时,我得到:

?- [nodes].
true.

?- listing(node).
node([1, 2]).
node([2, 3]).
node([3, 4]).
node([4, 6]).

true.

两个细节:

  1. 展开的谓词nodes_list/1 将出现在数据库中。
  2. term_expansion/2 的条款必须先于源文件中nodes_list/1的定义。

答案 1 :(得分:0)

CapelliC建议(在评论中)一个很好的答案(可能是最好的)是:

?-forall(member(X,[[1,2],[2,3],[3,4]]),assertz(node(X))).

你也可以写:

my_list(L):- member(X,L),assertz(node(X)).

示例:

?- my_list([[1,2],[2,3],[3,4]]).
true ;
true ;
true.
?- node([1,2]).
true ;
false.

感谢CapelliC的推荐,另一种方式是:

?- maplist(X>>assertz(node(X)), [[1,2],[2,3],[3,4]]).