我创建了一个prolog程序,它给出了一个List a List和Sublist将生成包含N个项目的子列表。我被告知这可以用1个事实和2个规则来完成。我得到了提示,我选择了第一个项目,或者我不会让我感到困惑。我有基本案例和第一个案例,但我希望有人可以帮我理解第二个案例。
choose(1, [H], [H]).
choose(N, [H,TL], [H|ST]) :- choose(Less1, TL, ST), Less1 is N-1.
所以我的第三条规则是要选择列表中的第二项
choose(N, [F,S|T], [S|ST]) :- choose(Less1, T, ST), Less1 is N-1.
然而,我的最后一条规则是不平衡的,整体不起作用。非常感谢任何想法!
答案 0 :(得分:2)
虽然this previous answer by @madanasta应该已经指出了正确的方向,但我们在此答案中使用clpfd对其进行了扩展:
:- use_module(library(clpfd)).
我们这样定义n_from_chosen/3
:
n_from_chosen(0,_,[]). n_from_chosen(N,[X|Es],[X|Xs]) :- N #> 0, N #= N0+1, n_from_chosen(N0,Es,Xs). n_from_chosen(N,[_|Es],Xs) :- N #> 0, n_from_chosen(N,Es,Xs).
示例查询:
?- n_from_chosen(2,[1,2,3,4],Xs). Xs = [1,2] ; Xs = [1,3] ; Xs = [1,4] ; Xs = [2,3] ; Xs = [2,4] ; Xs = [3,4] ; false.
这个更通用的查询怎么样?
?- n_from_chosen(N,[1,2,3],Xs). N = 0, Xs = [] ; N = 1, Xs = [1] ; N = 2, Xs = [1,2] ; N = 3, Xs = [1,2,3] ; N = 2, Xs = [1, 3] ; N = 1, Xs = [2 ] ; N = 2, Xs = [2,3] ; N = 1, Xs = [3] ; false.
答案 1 :(得分:1)
前两个条款背后的想法原则上是正确的。但是:
鉴于这些,您的问题的解决方案可能是:
<% if offer.merchant == 'webgains' or offer.merchant == 'aw' %>
<a href="<%= offer.url %>&clickref=<%= current_user.id %>" target="_blank">
<% elsif offer.merchant == 'rakuten' %>
<h1>WOOP</h1>
<% elsif offer.merchant == 'cj' %>
<a href="<%= offer.url %>?sid=<%= current_user.id %>" target="_blank">
<% else %>
<h1>FAIL</h1>
<a href="<%= offer.url %>" target="_blank">
<% end %>
尝试解释:
由于第三个条款,Prolog将能够为所要求的长度提供等于或大于1的替代解决方案。
一些结果:
choose(1, [H|_], [H]).
choose(N, [H|TL], [H|ST]) :- Less1 is N - 1, choose(Less1, TL, ST).
choose(N, [_|T], L) :- choose(N, T, L).
请注意,您不能像使用@repeat's solution一样使用此解决方案来解决具有未绑定长度变量的查询。要在纯Prolog中实现这一点,您必须稍微改变第二个子句背后的逻辑:
?- choose(2, [1,2,3,4], L).
L = [1, 2] ;
L = [1, 3] ;
L = [1, 4] ;
L = [2, 3] ;
L = [2, 4] ;
L = [3, 4] ;
false.
这也可能有助于澄清递归在这种情况下的工作原理。
希望这有帮助。
(免责声明:我相当肯定,人们可以更好地解释上述解决方案的工作原理(更不用说更好的解决方案)了。)