以下Prolog计划确定了保险费汽车保险。保险费取决于车辆的马力和驾驶员的年龄。
calculateCarInsurance(PS,Insurance) :-
PS < 60 , Insurance = 100.
calculateCarInsurance(PS,Insurance) :-
PS >= 60 , PS < 100 , Insurance = 200.
calculateCarInsurance(PS,Insurance) :-
PS >= 100 , Insurance = 300.
isInRiskyGroup(Age) :- Age < 25.
calculateCarInsurance(PS,Age,_) :- Age < 18 , fail.
calculateCarInsurance(PS,Age,Insurance) :-
Age >= 18 , isInRiskyGroup(Age) ,
calculateCarInsurance(PS,I2) ,
Insurance is I2 * 2.
calculateCarInsurance(PS,Age,Insurance) :-
not(isInRiskyGroup(Age)) ,
calculateCarInsurance(PS,Insurance).
现在需要 a)使用Green Cuts优化程序。 b)通过删除不需要的谓词,将绿色更改为红色削减。程序的行为应该是相同的。
我已经理解了prolog程序,但可以通过优化绿色削减来解决。 谢谢,任何人都可以用细节解释a,b。 感谢
答案 0 :(得分:5)
让我们从基础开始。剪切运算符为!
并且始终成功。切割不能回溯 - 它就像一个单向门。另一种看待它的方法是它会让你做出你迄今为止做出的决定。
剪辑的用法分为几类。根据定义,绿色切割是一种切割,它根本不会改变程序的运行时语义。绿色切割只是程序员告诉Prolog你已经知道你没有解决方案的一种方式。如果Prolog不知道没有更多解决方案,它会询问您是否需要其他解决方案,然后每次都失败。例如,请查看min/3
的实现:
min1(X, Y, X) :- X < Y.
min1(X, Y, Y) :- Y <= X.
?- min1(3, 4, X).
X = 3 ;
false.
看看Prolog如何问我是否需要其他解决方案,然后失败了?这证明堆栈上有一个额外的选择点。我们可以通过削减来消除它:
min2(X, Y, X) :- X < Y, !.
min2(X, Y, Y) :- Y =< X.
现在,当我们向Prolog询问min2/3
时,我们只会得到一个答案:
?- min2(3, 4, X).
X = 3.
看,没有提示,只有一个解决方案。
现在,与红色切割相比,这是一个绿色切割的原因是行为或推理没有真正的变化。只是Prolog无法知道X < Y
和Y =< X
是相互排斥的 - 绿色切割是我们告诉Prolog的方式,一旦你确定X小于Y,就没有意义了检查Y是否小于X.这将从堆栈中删除选择点,以获得技术。这有时是一个重要的优化,因为Prolog花了很多时间回溯,浪费了不必要的时间。
min/3
的第二个测试:
min3(X, Y, X) :- X < Y, !.
min3(_, Y, Y).
你可以这样思考自己,“当我们到达第二个句子时,我们知道X不小于Y,所以不需要检查并查看Y是否小于或等于X.”乍一看似乎是合理的,你会发现它看起来与min2/3
具有相同的行为,知道有一个像以前一样的解决方案:
?- min3(3, 4, X).
X = 3.
?- min3(4, 3, X).
X = 3.
然而,因为我们已经消除了一些逻辑,我们已经开放了涉及回溯的微妙错误。将min/3
视为三个实体之间的关系,我们可以使用min3/3
来产生min1/3
和min2/3
不存在的谎言:
?- min1(3, 100, 100).
false.
?- min2(3, 100, 100).
false.
?- min3(3, 100, 100).
true.
100不是3和100的最小值,但min3/3
将确认具有相同后两个值的任何内容,前提是第三个值不是变量。换句话说,我们假设在min3/3
中使用红色切割,我们永远不会在第三个位置显示值。我们假设我们将第三个参数用作“out”参数。
让我们学习这些知识并看看你的家庭作业。跳出来的第一件事就是前两条规则中存在同样的重叠条件逻辑:
calculateCarInsurance(PS,Insurance) :-
PS < 60, ...
calculateCarInsurance(PS,Insurance) :-
PS >= 60, ...
至少,我们可以在PS < 60
之后添加一个绿色切割来提交我们:如果PS小于60,它实际上也不能超过60,所以绿色切割绝对无害
我会提醒一个人想要添加红色剪辑。当你需要使用Prolog的推理来使它按照你想要的方式工作时,偶尔需要它们。在这种情况下,您可以注意到calculateCarInsurance
可能会返回多个解决方案。你可能不想要这种行为,你可能想要提交你得到的第一个。在这种情况下,您可以在calculateCarInsurance
规则的所有实体的末尾添加一个剪切。无论Prolog能找到多少解决方案,您都可以获得单一解决方案。这会改变程序的逻辑行为,但可能需要,具体取决于您的要求。这也可能具有min3/3
的相同负面副作用,但如果我们想验证保险结果,calculateCarInsurance
可能会肯定它永远不会产生的计算。
我希望这足以让你走上正轨。