Syntax 学习prolog/haskell编程考试
我开始为即将到来的考试而学习,我被困在一个琐碎的序言练习题上,这不是一个好兆头 这应该很容易,但由于某种原因,我现在无法理解 任务是简单地计算prolog中Int列表中的奇数。 我在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的定义很好 空列表的事实也很好 在
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
).
在第一个版本中,递归调用遵循testodd(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
).
在第一个版本中,递归调用遵循testodd(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).
非常感谢,在这个问题上以及我遇到的其他问题上帮了我的忙:)非常感谢,在这个问题上以及我遇到的其他问题上帮了我的忙:)