gpt4 book ai didi

macros - 术语列表的术语扩展

转载 作者:行者123 更新时间:2023-12-01 23:53:39 24 4
gpt4 key购买 nike

假设我想要一些都遵循相同模式的规则。当我想通过明确列出所有可能的第一个参数来避免非确定性行为时,我遇到了这种情况。但是,我知道对于某些可能性,我需要做完全相同的事情。处理它的一种方法是在最后添加一个包罗万象的子句:

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

但这不是很好,因为我实际上无法知道是否有意外输入,或者我是否在我的程序中犯了错误。为了避免这种情况,我也可以说
foo(X) :- memberchk(X, [ /* list of possible values of X */ ]).

但同样,当论证成立时,我现在正在与 Prolog 的确定性行为和索引作斗争。

所以,相反,我做这样的事情:
term_expansion(foos(Foos), Foo_rules) :-
maplist(expand_foo, Foos, Foo_rules).

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

问题是,我试图找到这样的现有代码,但我不能。是因为我做错了什么吗?有没有更好的方法来解决这个问题?还是完全规避?

我不介意回答说“你解决了错误的问题”。

编辑:一些谷歌搜索实际上让我从 SWI-Prolog 文档中找到了这个非常相似的例子:

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

最佳答案

首先对您已经建议的变体发表一些评论:

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

这样做的主要问题是最后一个条款 ( foo(_) ) 适用于其他 - 大概更专业的 - 条款也适用的情况。所以查询 ?- foo(a).现在无意中是不确定的。

你说这个版本“不是很好,因为我实际上不知道是否有意外输入,或者我是否在我的程序中犯了错误”。我们可以通过在 check-all 子句中确保给定的术语不是意外的来防止意外输入:
foo(a) :- /* do something */.
foo(b) :- /* do something else */.
foo(X) :- must_be(oneof([a,b,x,y], X).

当术语具有意外形式时,这会引发错误。我用过 xy作为未特别处理的术语的示例。请注意 ab当然必须包括在内,因为该条款(再次)也适用于两者。即使实例化了谓词,谓词仍然不是确定性的,因为第一个参数索引无法区分情况。您写道“当论证成立时,我现在正在与 Prolog 的确定性行为和索引作斗争”,并且可能(并且正确地)意味着您在使用这种表示时无法从这些功能中受益。

现在是不错的声明式解决方案 :每次你想引入“catch-all”或“default”子句时,重新考虑你的数据表示,并为可以应用的不同情况引入区分仿函数。在您的示例中,两种情况是:
  • 这个词需要特殊处理
  • 这个词不需要做任何特别的事情。

  • 我会用 special(_)ordinary(_)来区分情况。因此:
    foo(special(S)) :- foo_special(S).
    foo(ordinary(_)). % do nothing

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

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

    关于macros - 术语列表的术语扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25203182/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com