【发布时间】:2014-10-02 22:09:05
【问题描述】:
当我对我在 Prolog 中的数据结构提出批评时,我在这里向专家寻求替代解决方案。
例如,我有一个 XML 中的配方描述数据集
<recipeml fileversion="13.8.2014">
<recipe>
<head>
<title>Green Soup</title>
</head>
<ing-div type="titled">
<title>soup</title>
<ingredients>
<ing>
<amt><qty>500</qty><unit>gramm</unit></amt>
<item>pea</item>
</ing>
<ing>
<amt><qty>200</qty><unit>ml</unit></amt>
<item>cream</item>
</ing>
...
</ingredients>
</ing-div>
<directions>
<step>Do something, cooking ....</step>
<step>Next do again something...</step>
...
</directions>
</recipe>
<recipe>
...
</recipe>
...
</recipeml>
我选择使用列表将它作为迭代元素树存储在 Prolog 中:
database([element('recipeml',[version=0.5],
[element('recipe',[],
[element('head',[],
[element('title',[],['Green Soup']
)]
),
element('ing-div',[type=titled],
[element('title',[],['soup']),
element('ingredients',[],
[element(ing,[],
[ element(amt,[],
[ element(qty,[],['500']), element(unit,[],[gramm]),]),
element(item,[],['pea'])
]),
element(ing,[],
[ element(amt,[],
[ element(qty,[],['200']), element(unit,[],[ml]),]),
element(item,[],['pea'])
])
]
)]
)]
),
element('recipe',[],...
)]
)]).
我想做的是根据用户输入轻松查找食谱。 用户可能会提供一种成分或部分配方名称作为输入。
实际上我是通过
ask_element(Name, Child, Parent) :-
(
member( element(Name,_,Child),Parent)
;
member( element(_,_,NewParent),Parent),
[_|_] = NewParent,
ask_element(Name, Child, NewParent)
).
我得到了所有带有特殊成分的食谱
findall(RTitle,
(
ask_element('recipe',RKnot,Knot),
ask_element('item',TmpIng,RKnot),
contains(TmpIng,Ingredient),
[Ing|_] = TmpIng, % avoid brackets [Egg]
define_xml_knot(['head','title'],_,RKnot,TmpRTitle),
[RTitle|_] = TmpRTitle % avoid brackets [Soup]
,Bag),
然后我的结果是食谱标题的列表。如果输入成分列表,我需要 第二个分析步骤以获取具有最匹配成分的配方。也许这是 不是真正的 Prolog 风格?
根据 Paulo Moura 的评论(谢谢),一个想法是将数据排列为
recipe(IDnumber,'Green Soup',ingredients(item(500,gramm,'pea'),item(200,ml,'cream')),steps('Do something','Next step do again something')).
我不确定这是否真的有帮助。寻找具有某种成分的食谱,如果包含我正在寻找的成分(或单词的一部分),我必须通过每个项目一步一步地再次查看每个食谱。如果我想添加一个新的描述符,例如“level(easy)”随着recipe() 中元素数量的变化,我必须更改所有数据调用。使用element(element...) 构造,我不必更改调用。
但是响应会更好,只返回 ID 号,然后我在一次“调用”(recipe(123,X,Y,Z)) 中获取整个配方以进行进一步处理。其实我
如您在上面的“Bag”中看到的那样,作为响应“列表中的字符串文本”返回......
这是我在 Prolog 中的第一个应用程序,所以我对足够的数据存储不是很熟悉。我会很感激每一个提示。
【问题讨论】:
-
在我的建议中,成分和步骤将有一个参数,分别是成分和步骤的列表。 IE。使用您的示例
recipe(IDnumber,'Green Soup',ingredients([item(500,gramm,'pea'),item(200,ml,'cream')]),steps(['Do something','Next step do again something'])).。将成分和步骤作为具有取决于配方的数量的复合术语只会使处理复杂化而没有任何好处。这也将更接近地反映您呈现的 XML 结构(假设这是您的意图)。