Prolog - 如何使 Prolog 查询更短?

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

我一直在尝试学习 Prolog,这个特殊的事情已经困扰我一段时间了:为了完成任何事情,我的查询需要长得惊人。特别是,我有以下代表简单分类程序的片段:

% Define the objects
object(pencil, stationery).
object(apple, organic).
object(eraser, stationery).
object(book, stationery).
object(mouse, electronic).
object(mp3, electronic).
object(ipad, electronic).

% Define the baskets
basket(red_basket, electronic).
basket(tall_basket, stationery).
basket(round_basket, organic).

% Define the sorting rule
sort_object(Object, Basket) :-
    object(Object, Type),
    basket(Basket, Type).

% Query the program to sort the objects into the baskets
% How can we reduce this last statement to be MUCH shorter?
?- sort_object(pencil, Basket1), sort_object(apple, Basket2), sort_object(eraser, Basket3), sort_object(book, Basket4), sort_object(mouse, Basket5), sort_object(mp3, Basket6), sort_object(ipad, Basket7).

我喜欢所有术语定义都尽可能简洁,但最终的查询对我来说太长了,感觉不对。相反,如果我们要在 Elixir 中实现同样的事情,人们可能会这样做:

defmodule DB do
  def objects do
    [:pencil, :iPad, :basketball, :laptop, :apple]
  end
end

defmodule ObjectHelper do
  def get_type(:pencil), do: :stationery
  def get_type(:iPad), do: :electronics
  def get_type(:basketball), do: :sport
  def get_type(:laptop), do: :electronics
  def get_type(:apple), do: :food
end

defmodule BasketHelper do
  def get_basket(:electronics), do: :red
  def get_basket(:stationery), do: :yellow
  def get_basket(_), do: :blue
end

DB.objects
|> Enum.group_by(fn o -> o |> ObjectHelper.get_type |> BasketHelper.get_basket end)
|> IO.inspect

目标是为每个对象输出正确的篮子,您可以想象在 C++ 或 Python 中轻松干净地完成此操作,尽管代码较长。

我的问题是:

  1. 是否有任何构造可以允许更简洁的查询?
  2. 如果我的问题有什么“错误” - 也许为了在实践中完成这项任务,有更好的方法来表述问题?

我正在使用 SWI Prolog。
谢谢!

syntax prolog swi-prolog
1个回答
0
投票

首先,将

sort_object
重命名为基于关系的名称,而不是操作名称,因为更适合这种双向查找(特别是因为不涉及 sort):

object_basket(Object, Basket) :-
    object(Object, Type),
    basket(Basket, Type).

然后,可以使用maplist:

?- Objects = [pencil, apple, eraser, book, mouse, mp3, ipad],
   maplist(object_basket, Objects, Baskets).
Objects = [pencil, apple, eraser, book, mouse, mp3, ipad],
Baskets = [tall_basket, round_basket, tall_basket, tall_basket, red_basket, red_basket, red_basket].
© www.soinside.com 2019 - 2024. All rights reserved.