List 列表和上的参数没有充分实例化

List 列表和上的参数没有充分实例化,list,prolog,instantiation,swi-prolog,clpfd,List,Prolog,Instantiation,Swi Prolog,Clpfd,我试图约束列表的总和,但我的代码在label()处失败 .pl: 有什么想法吗 编辑: 运行调试器:,我认为错误在label()中,此时: finite_domain(Var) :- ( fd_get(Var, Dom, _) -> ( domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> true ; instantiation_error(Va

我试图约束列表的总和,但我的代码在
label()
处失败

.pl:

有什么想法吗


编辑:

运行调试器:,我认为错误在
label()
中,此时:

finite_domain(Var) :-
        (   fd_get(Var, Dom, _) ->
            (   domain_infimum(Dom, n(_)), domain_supremum(Dom, n(_)) -> true
            ;   instantiation_error(Var)
            )
        ;   integer(Var) -> true
        ;   must_be(integer, Var)
        ).

使用图形调试器单步执行代码:

?- gtrace, solve(L, 5).
正如您将看到的,
label/1
与此错误没有任何关系

使用CLP(FD)约束,而不是
sum\u list/2
:它可以在各个方向工作,让您看到查询的答案

我建议你退后一步,认真考虑你在这里做什么。< /P> 例如,为什么要将副作用(
write/1
)与纯代码混用?专注于对问题的清晰的声明性描述,让顶层为您做报告

此外,如此频繁地需要额外的逻辑谓词(如
(==)/2
)也是非常罕见的。例如,写:

sublists_below_center(_, _, Dim, End) :-
    End #= Dim - 2.
在不使用额外的逻辑语言元素的情况下,使参数之间的关系完全清楚

使用
flatte/2
几乎总是一个坏主意,通常表明数据结构设计中存在问题。使用
append/2
删除一级嵌套

如果已经导入CLP(FD)库,为什么还要使用基本算术?在整个过程中使用
(#=)/2


此外,谓词名称表明您对问题的思考过于迫切。专注于问题解决方案的纯声明性描述,Prolog将为您完成其余的工作。避免使用命令式名称。取而代之的是,使用描述在什么条件下保持什么的名称。

使用图形调试器逐步完成代码:

?- gtrace, solve(L, 5).
正如您将看到的,
label/1
与此错误没有任何关系

使用CLP(FD)约束,而不是
sum\u list/2
:它可以在各个方向工作,让您看到查询的答案

我建议你退后一步,认真考虑你在这里做什么。< /P> 例如,为什么要将副作用(
write/1
)与纯代码混用?专注于对问题的清晰的声明性描述,让顶层为您做报告

此外,如此频繁地需要额外的逻辑谓词(如
(==)/2
)也是非常罕见的。例如,写:

sublists_below_center(_, _, Dim, End) :-
    End #= Dim - 2.
在不使用额外的逻辑语言元素的情况下,使参数之间的关系完全清楚

使用
flatte/2
几乎总是一个坏主意,通常表明数据结构设计中存在问题。使用
append/2
删除一级嵌套

如果已经导入CLP(FD)库,为什么还要使用基本算术?在整个过程中使用
(#=)/2


此外,谓词名称表明您对问题的思考过于迫切。专注于问题解决方案的纯声明性描述,Prolog将为您完成其余的工作。避免使用命令式名称。取而代之的是,使用描述在什么条件下保持什么的名称。

一种方法是运行跟踪,然后重试查询。键入
跟踪。
然后执行查询。每个步骤都将详细显示,直到找到问题为止。它会指出问题所在。谢谢潜伏者,从现在起我会记住这一点!这是一个方便的工具。有时你需要提供一个非常简单的例子,但失败了,或者你可以在那里一整天的跟踪!一种方法是运行跟踪,然后再次尝试查询。键入
跟踪。
然后执行查询。每个步骤都将详细显示,直到找到问题为止。它会指出问题所在。谢谢潜伏者,从现在起我会记住这一点!这是一个方便的工具。有时你需要提供一个非常简单的例子,但失败了,或者你可以在那里一整天的跟踪!