prolog - 为什么'mary'是真的两次?
问题描述
我有一个 Prolog 程序应该返回pass(mary)
一次 true,除了我的返回两次,我不确定为什么。
该程序旨在检查是否Student
通过了他们的课程。它检查:
- 如果他们的编程课程
Student
足够高,Mark
- 他们没有考试不及格,
- 看看他们在考试中的平均成绩是否在40以上,
- 如果他们的课程超过 50;如果不是,那么他们在考试中的平均成绩必须达到 50 或以上才能通过。
根据我所掌握的事实,“玛丽”通过(她应该),而其他人失败(他们也应该),但“玛丽”出于某种原因两次为真。
事实(只是“玛丽”):
coursework(mary, 75).
programming(mary, 70).
e1(mary, 60).
e2(mary, 65).
e3(mary, 70).
marks(mary, [60, 65, 70]).
代码:
sum([], 0).
sum([X|Tail], Sum):-
sum(Tail, Temp),
Sum = Temp + X.
avg(List, Avg):-
sum(List, Sum),
length(List, Length),
Length > 0,
Avg is Sum / Length.
examFail(Student):-
( e1(Student, MarkE1),
MarkE1 < 30
; e2(Student, MarkE2),
MarkE2 < 30
; e3(Student, MarkE3),
MarkE3 < 30
).
courseworkCheck(Student):-
( coursework(Student, Mark),
Mark > 49
; marks(Student, List),
avg(List, Avg),
Avg > 49
).
pass(Student):-
programming(Student, Mark),
Mark > 29,
\+ examFail(Student),
marks(Student, List),
avg(List, Avg),
Avg > 39,
courseworkCheck(Student).
有什么我做错了吗?
解决方案
pass(mary)
如果courseworkCheck/1
仅限于其中一种替代方案,您的程序已经成功。也就是说,两者
课程检查(学生):- (课程作业(学生,马克), 标记 > 49 ;标记(学生,列表),平均(列表,平均),平均> 49,假)。
和
课程检查(学生):- (coursework(Student, Mark),Mark > 49, false; 标记(学生,列表), 平均(列表,平均), 平均 > 49 )。
成功。本质上,这不是问题。最好的办法是通过包装setof(t, courseworkCheck(Student), _)
或减少开销setof(t,pass(Student),_)
。而是谨慎使用此设备。
否则,Avg >= 50
最好是Avg > 49
。毕竟,总有一天Avg = 49.5
会发生......