Syntax 学习prolog/haskell编程考试

Syntax 学习prolog/haskell编程考试,syntax,prolog,Syntax,Prolog,我开始为即将到来的考试而学习,我被困在一个琐碎的序言练习题上,这不是一个好兆头 这应该很容易,但由于某种原因,我现在无法理解 任务是简单地计算prolog中Int列表中的奇数。 我在haskell很容易做到,但我的开场白很糟糕。有人能告诉我一个简单的方法来做这件事,并简要地解释一下你做了什么 到目前为止,我已经: odd(X):- 1 is X mod 2. countOdds([],0). countOdds(X|Xs],Y):- ????? 你对奇数/1的定义很好 空列表的事实也很好 在

我开始为即将到来的考试而学习,我被困在一个琐碎的序言练习题上,这不是一个好兆头

这应该很容易,但由于某种原因,我现在无法理解

任务是简单地计算prolog中Int列表中的奇数。 我在haskell很容易做到,但我的开场白很糟糕。有人能告诉我一个简单的方法来做这件事,并简要地解释一下你做了什么

到目前为止,我已经:

odd(X):- 1 is X mod 2.

countOdds([],0).
countOdds(X|Xs],Y):-
?????

你对奇数/1的定义很好

空列表的事实也很好

在递归子句中,需要区分奇数和偶数。如果数字为奇数,则应增加计数器:

countOdds([X|Xs],Y1) :- odd(X), countOdds(Xs,Y), Y1 is Y+1.
如果数字不是奇数(=偶数),则不应增加计数器

countOdds([X|Xs],Y) :- \+ odd(X), countOdds(Xs,Y).
其中
\+
表示否定为失败

或者,您可以使用!在第一个递归子句中,并在第二个递归子句中删除条件:

countOdds([X|Xs],Y1) :- odd(X), !, countOdds(Xs,Y), Y1 is Y+1.

countOdds([X|Xs],Y) :- countOdds(Xs,Y).

你对奇数/1的定义很好

空列表的事实也很好

在递归子句中,需要区分奇数和偶数。如果数字为奇数,则应增加计数器:

countOdds([X|Xs],Y1) :- odd(X), countOdds(Xs,Y), Y1 is Y+1.
如果数字不是奇数(=偶数),则不应增加计数器

countOdds([X|Xs],Y) :- \+ odd(X), countOdds(Xs,Y).
其中
\+
表示否定为失败

或者,您可以使用!在第一个递归子句中,并在第二个递归子句中删除条件:

countOdds([X|Xs],Y1) :- odd(X), !, countOdds(Xs,Y), Y1 is Y+1.

countOdds([X|Xs],Y) :- countOdds(Xs,Y).

在Prolog中,使用递归检查递归数据结构的元素,就像列表一样。 模式匹配允许选择要应用的正确规则。 完成任务的简单方法:

对于每个元素X,都有一个列表=[X | Xs],if为奇数(X)return countrobits(Xs)+1 else返回countrobits(Xs)

注意,
如果
,则使用具有相同模式的不同规则处理:
当Prolog找到非奇数元素时,它返回到最后一个规则

ISO Prolog有
If-Then-Else
的语法sugar,您可以使用它编写代码

countOdds([], 0).
countOdds([X|Xs], C) :-
  countOdds(Xs, Cs),
  (  odd(X)
  -> C is Cs + 1
  ;  C is Cs
  ).
在第一个版本中,递归调用遵循test
odd(X)
,以避免在回溯时重复对list'tail的无用访问

编辑如果不剪切,我们会得到多个执行路径,因此在“所有解决方案”谓词(findall、setof等)下可能会得到不正确的结果

最后一个版本证明了该过程不是
尾部递归的
。要获取尾部递归过程,请添加一个
累加器

countOdds(L, C) :- countOdds(L, 0, C).

countOdds([], A, A).
countOdds([X|Xs], A, Cs) :-
  (  odd(X)
  -> A1 is A + 1
  ;  A1 is A
  ),
  countOdds(Xs, A1, Cs).

在Prolog中,使用递归检查递归数据结构的元素,就像列表一样。 模式匹配允许选择要应用的正确规则。 完成任务的简单方法:

对于每个元素X,都有一个列表=[X | Xs],if为奇数(X)return countrobits(Xs)+1 else返回countrobits(Xs)

注意,
如果
,则使用具有相同模式的不同规则处理:
当Prolog找到非奇数元素时,它返回到最后一个规则

ISO Prolog有
If-Then-Else
的语法sugar,您可以使用它编写代码

countOdds([], 0).
countOdds([X|Xs], C) :-
  countOdds(Xs, Cs),
  (  odd(X)
  -> C is Cs + 1
  ;  C is Cs
  ).
在第一个版本中,递归调用遵循test
odd(X)
,以避免在回溯时重复对list'tail的无用访问

编辑如果不剪切,我们会得到多个执行路径,因此在“所有解决方案”谓词(findall、setof等)下可能会得到不正确的结果

最后一个版本证明了该过程不是
尾部递归的
。要获取尾部递归过程,请添加一个
累加器

countOdds(L, C) :- countOdds(L, 0, C).

countOdds([], A, A).
countOdds([X|Xs], A, Cs) :-
  (  odd(X)
  -> A1 is A + 1
  ;  A1 is A
  ),
  countOdds(Xs, A1, Cs).

非常感谢,在这个问题上以及我遇到的其他问题上帮了我的忙:)非常感谢,在这个问题上以及我遇到的其他问题上帮了我的忙:)