列表中的偶数和奇数元素以及计数元素直到列表中的特定索引,但显示错误

发布于 2025-01-14 20:22:13 字数 1320 浏览 1 评论 0原文

我正在制作一个 prolog 程序来计算列表中的偶数和奇数元素,并将元素计数到列表中的特定索引(用户给定)。但它显示错误。我是序言中的新人。这是我的代码:

is_even(N) :- Y is N mod 2, Y=0.

split(Index,List,Left,Right) :-
   length(Left,Index),       % Actually CREATES a list of fresh variables if "Left" is unbound
   append(Left,Right,List).  % Demand that Left + Right = List.

create(L1):-read(Elem),create(Elem,L1).

create(-1,[]):-!. create(Elem,[Elem|T]):-read(Nextel),create(Nextel,T).

setval(Y8,0).
setval(Y9,0).

incr():-
 Y8 is Y8 + 1.

incb():-
 Y9 is Y9 + 1.
 
count(R):-
 ( is_even(R) -> incr();incb()).
 
dosomething([]).
 dosomething([R|T]) :- count(R), dosomething(T).
 
go:- write('Creating a list'),nl, write('Enter -1 to stop'),nl, create(L), nl, write('Enter index'),read(ID), split(ID,L,X1,X2), dosomething(X1), write(Y8), write(Y9).

它给了我以下错误:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [14] _19326 is _19332+1
ERROR:   [11] dosomething([1,2]) at c:/users/v/documents/prolog/bw.pl:24
ERROR:   [10] go at c:/users/v/documents/prolog/bw.pl:26
ERROR:    [9] toplevel_call(user:user:go) at c:/program files/swipl/boot/toplevel.pl:1117
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

I am making a prolog program to count even and odd elements from list and count elements up to a specific index(user given) in the list. But it shows Errors. I am new in prolog. Here is my code:

is_even(N) :- Y is N mod 2, Y=0.

split(Index,List,Left,Right) :-
   length(Left,Index),       % Actually CREATES a list of fresh variables if "Left" is unbound
   append(Left,Right,List).  % Demand that Left + Right = List.

create(L1):-read(Elem),create(Elem,L1).

create(-1,[]):-!. create(Elem,[Elem|T]):-read(Nextel),create(Nextel,T).

setval(Y8,0).
setval(Y9,0).

incr():-
 Y8 is Y8 + 1.

incb():-
 Y9 is Y9 + 1.
 
count(R):-
 ( is_even(R) -> incr();incb()).
 
dosomething([]).
 dosomething([R|T]) :- count(R), dosomething(T).
 
go:- write('Creating a list'),nl, write('Enter -1 to stop'),nl, create(L), nl, write('Enter index'),read(ID), split(ID,L,X1,X2), dosomething(X1), write(Y8), write(Y9).

It gives me the following error:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [14] _19326 is _19332+1
ERROR:   [11] dosomething([1,2]) at c:/users/v/documents/prolog/bw.pl:24
ERROR:   [10] go at c:/users/v/documents/prolog/bw.pl:26
ERROR:    [9] toplevel_call(user:user:go) at c:/program files/swipl/boot/toplevel.pl:1117
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

杀お生予夺 2025-01-21 20:22:13

您的代码存在几个问题,也许您应该重新考虑一种更简单的方法。

首先,适用于任何编程语言的软件工程原则指出,您应该尽可能避免全局变量。因此,您应该使用 - 例如 - Yn is Y + 1,而不是 incr():- Y8 is Y8 + 1.

另请注意,由于在 Prolog 中变量分配一次,Y8 is Y8 + 1永远为真,然后谓词 incr/0 将总是失败。

另一个小问题:incr():-... 是一个 SWI-Prolog 语法扩展,引入它是为了支持 OOP 的受限形式,您应该使用普通的 Prolog 语法 incr :- ...

无论如何,尝试使用单个“循环”(即递归谓词)来解决您的作业,您可以在其中传递要检查的元素的索引,并返回说明您要求检查的属性的计数器。如果我正确理解了这个问题,您还应该检查元素是否实际上是整数,对它们进行计数,并仅对它们应用奇数/偶数检查。在下面的代码片段中,我使用传统参数排序,将输入放在输出之前。您应该在 count/6 第一个子句的适当位置放置一个剪切,并且 - 当然 - 提供适当的谓词 update_counters/7。

count([E|Es],N,I, Int,Odd,Even) :-
  I=<N, I1 is I+1,
  count(Es,N,I1, Int1,Odd1,Even1),
  update_counters(E, Int1,Int, Odd1,Odd, Even1,Even).
count(_,_,_,0,0,0).

There are several problems with your code, maybe you should rethink it a simpler way.

First, a SW engineering principle valid in any programming language, states that you should avoid global variables, as far as possible. So, instead of incr():- Y8 is Y8 + 1., you should use - for example - Yn is Y + 1.

Note also that since in Prolog variables are assign once, Y8 is Y8 + 1 will never be true, and then the predicate incr/0 will always fail.

Another - minor - problem: incr():-... is a SWI-Prolog syntactic extension, introduced to support a restricted form of OOP, you should use instead the plain Prolog syntax incr :- ....

Anyway, try to solve your assignment with a single 'loop', that is, a recursive predicate, where you pass down the index of the element to check, and get back the counters accounting for the properties you're asked to check. If I understand the question correctly, you should also check that elements are actually integers, count them, and apply the odd/even check only on them. In the following snippet, I use the conventional arguments ordering, placing the input before the output. You should place a cut in the appropriate place in the first clause of count/6, and - of course - provide an appropriate predicate update_counters/7.

count([E|Es],N,I, Int,Odd,Even) :-
  I=<N, I1 is I+1,
  count(Es,N,I1, Int1,Odd1,Even1),
  update_counters(E, Int1,Int, Odd1,Odd, Even1,Even).
count(_,_,_,0,0,0).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文