如何表示嵌套对象

问题描述 投票:0回答:1

我最近对 Prolog 以及如何使用它来表示和查询比我随处可见的常见父/子示例更真实的数据集感到好奇。

为了玩玩,我生成了一个具有以下结构的小数据集:

books:
  - titles:
      - My first book
      - My first attempt at a book
    authors:
      - firstname: Alice
        lastname: Ecila
      - firstname: Bob
        lastname: Obb

经过几次尝试,我最终得到了这样的东西:

book(1).

title(book(1), "My first book").
title(book(1), "My first attempt at a book").

author(book(1)).

firstname(author(book(1)), "Alice").
firstname(author(book(1)), "Bob").

lastname(author(book(1)), "Ecila").
lastname(author(book(1)), "Obb").

这对于查询有关书籍的信息非常有效,但我完全失去了嵌套对象属性之间的关系。例如,没有办法知道

lastname
Alice
。另一方面,如果我尝试将书籍表示为这样的单个术语:

book(
  title("My first book"),
  author(
    firstname("Alice"),
    lastname("Ecila")
  )
).
book(
  title("My first book"),
  author(
    firstname("Bob"),
    lastname("Obb")
  )
).
book(
  title("My first attempt at a book"),
  author(
    firstname("Alice"),
    lastname("Ecila")
  )
).
book(
  title("My first attempt at a book"),
  author(
    firstname("Bob"),
    lastname("Obb")
  )
).

或者这个:

book(
  [ title("My first book"),
    title("My first attempt at a book")
  ],
  [ author(
      firstname("Alice"),
      lastname("Ecila")
    ),
    author(
      firstname("Bob"),
      lastname("Obb")
    )
  ]
).

我要么丢失了一定数量的信息,要么变得太复杂而无法查询。树似乎很简单,可以表示,但一般来说,图形似乎更复杂。

所以这是我的问题:在序言中表示复杂的嵌套对象的首选方法是什么?

我也在寻找关于这个特定主题的样本和/或文献。

prolog
1个回答
2
投票

只需将它们放在桌子上即可。例如:

book(1).

book_title(1, 'My first book').
book_title(1, 'My first attempt at a book').

book_author(1, 'Alice', 'Ecila').
book_author(1, 'Bob', 'Obb').

book_titles(B, Ts) :-
    bagof(title(T), book_title(B, T), Ts).

book_authors(B, As) :-
    bagof(author(firstname(X), lastname(Y)), book_author(B, X, Y), As).

book_titles_authors(B, book(B, Ts, As)) :-
    book_titles(B, Ts),
    book_authors(B, As).

如您所见,您实际上可以在 Prolog 中编写查询。我这样做只是为了表明一旦您拥有关系数据,就可以很容易地查询它并将它们放在一起,如果您愿意,可以嵌套。

?- book_titles_authors(1, Book).
Book = book(1,
            [title('My first attempt at a book'),
             title('My first book')
            ],
            [author(firstname('Alice'),
                    lastname('Ecila')),
             author(firstname('Bob'),
                    lastname('Obb'))
            ]).

这里是典型的 RDBMS 和 vanilla Prolog 之间的一些区别:

  • Prolog 表中的列具有位置,而不是名称。你看到上面的名字/姓氏。
  • 在 Prolog 中,结果的顺序是明确定义的。
  • 约束和键不是语言的一部分。
  • 在Prolog中,它是一个内存数据库。
  • 您没有查询规划器和优化器。

请记住这是普通的 Prolog。由于 Prolog 是一种高级通用编程语言,您可以通过一些努力来实现其中的任何一种。一些功能已经作为库存在。

Prolog 作为一种查询语言的一个巨大优势是它的组合非常好,这与 SQL 不同。

© www.soinside.com 2019 - 2024. All rights reserved.