术语扩展以获取术语列表 [英] Term expansion for a list of terms

查看:116
本文介绍了术语扩展以获取术语列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我想拥有许多遵循相同模式的规则.当我想通过明确列出所有可能的第一个参数来避免非确定性行为时,就遇到了这种情况.但是我知道,对于某些可能性,我需要做完全相同的事情.解决它的一种方法是在结尾处使用一个包罗万象的子句:

Say I want to have a number of rules that all follow the same pattern. I have ran into this situation when I want to avoid non-deterministic behavior by explicitly listing all possible first arguments. I know, however, that I need to do exactly the same for some of the possibilities. One way to deal with it would be to have a catch-all clause at the end:

foo(a) :- /* do something */.
foo(b) :- /* do something else*/.
foo(_). /* ignore the rest */

但这不是很好,因为我实际上不知道是否收到了意外的输入,或者我在程序中犯了一个错误.为了避免这种情况,我也可以说

but this is not very nice because I can't actually know if got unexpected input, or if I made a mistake in my program. To avoid this, I could also say

foo(X) :- memberchk(X, [ /* list of possible values of X */ ]).

但是,再次,我现在正在与Prolog的确定性行为和索引论证时的索引作斗争.

but again, I am now fighting against Prolog's deterministic behavior and indexing when the argument is ground.

因此,我做这样的事情:

So, instead, I do something like this:

term_expansion(foos(Foos), Foo_rules) :-
    maplist(expand_foo, Foos, Foo_rules).

expand_foo(Foo, foo(Foo)).
other_foos([x,y,z]).

问题是,我有点想找到这样的现有代码,但我找不到.是因为我做错了吗?有没有更好的方法来解决此问题?还是完全规避它?

The thing is, I sort of tried to find existing code like this and I couldn't. Is it because I am doing something wrong? Is there a better way to approach this problem? Or circumvent it altogether?

我不介意回答您正在解决错误的问题".

I don't mind answers that say "you are solving the wrong problem".

实际上,有些搜索使我了解了SWI-Prolog文档中的这个非常相似的示例:

Some googling actually got me to this very similar example from the SWI-Prolog documentation:

http://www.swi-prolog.org/pldoc/man?section = ext-dquotes-motivation (在最底部)

推荐答案

首先,对您已经建议的变体进行一些评论:

First a few comments on the variants you already suggest:

foo(a) :- /* do something */.
foo(b) :- /* do something else */.
foo(_).   /* ignore the rest */

主要问题是,最后一个子句(foo(_))在另一个(可能是更专门的)子句 适用的情况下适用.因此,查询?- foo(a).现在是无意的不确定性.

The main problem with this is that the final clause (foo(_)) applies when the other - presumably more specialized - clauses also apply. So the query ?- foo(a). is now unintentionally non-deterministic.

您说此版本不是很好,因为我实际上不知道是否收到了意外输入,或者我在程序中犯了错误".我们可以通过在check-all子句中确保给定的术语不是意外的来防止意外的输入:

You say this version "is not very nice because I can't actually know if got unexpected input, or if I made a mistake in my program". We could guard against unexpected input by making sure, in the check-all clause, that the given term is not unexpected:

foo(a) :- /* do something */.
foo(b) :- /* do something else */.
foo(X) :- must_be(oneof([a,b,x,y], X).

当术语为意外形式时,这会引发错误.我使用xy作为未特殊处理的术语的示例.请注意,当然必须包括ab,因为(再次)该条款也适用于它们两个.即使实例化其参数,该谓词仍然不是确定性的,因为第一个参数索引无法区分大小写.您写道:现在我正在反对Prolog的确定性行为和当论点成立时建立索引",并且可能(并且正确地)意味着,当您使用这种表示形式时,您将无法从这些功能中受益.

This raises an error when the term is of an unexpected form. I used x and y as examples for terms that are not handled specially. Note that a and b must of course be included, because the clause (again) applies to both of them as well. The predicate is still not deterministic even when its argument is instantiated, because first argument indexing cannot distinguish the cases. You write "I am now fighting against Prolog's deterministic behavior and indexing when the argument is ground" and probably (and correctly) mean that you cannot benefit from these features when you use this representation.

现在是一个不错的声明性解决方案:每次尝试引入包罗万象"或默认"子句时,请重新考虑数据表示形式,并针对不同情况引入区分函子可以申请.在您的示例中,两种情况是:

And now the nice declarative solution: Every time you are tempted to introduce a "catch-all" or "default" clause, reconsider your data representation, and introduce distinguishing functors for the different cases that can apply. In your example, the two cases are:

  1. 该术语需要以特殊方式处理
  2. 该术语不需要做任何特殊的事情.

我将使用special(_)ordinary(_)来区分情况.因此:

I will use special(_) and ordinary(_) to distinguish the cases. Thus:

foo(special(S)) :- foo_special(S).
foo(ordinary(_)). % do nothing

foo_special(a) :- /* do something      */
foo_special(b) :- /* do something else */

这些谓词可以在所有方向上使用,并且在知道参数时是确定性的.类型检查可以轻松添加.

These predicates can be used in all directions, and are deterministic when the argument is known. Type-checks can be added easily.

这篇关于术语扩展以获取术语列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆