English 中文(简体)
更多涉及建造 pro名单的问题
原标题:More trouble with prolog list building
  • 时间:2012-04-10 17:54:50
  •  标签:
  • prolog

I m sorry to post another question on this, but I just seem to be going in circles here!

For my program I need to make a list of lists, with each sublist containing 2 numbers, X and Y along with the sum and product of these 2 numbers. So far I have the following:

genList(100,N, X,[]).

genList(S,N, X,[[X,Y,Sum,Product]|Xs]):-

    Y is N+1,
    Sum is X+Y,
    NewS is Sum,
    Sum<101,
    Product is X*Y,
    N1 is N+1,
    genList(NewS,N1, X,Xs).

genList(S,N,X,Q):-
    N+X < 101,
    NextX is X + 1,
    genList(0,NextX,NextX,Q).

目标是找到每个数字乘以总和;=100。 因此,从上到上看,每张1 <X <Y,在那里,总和;=100,并随附所有数字。 2-N将提供一份完整的可能奶制品清单。

For those interested, the problem I m working through is the sum/product problem, described here (Second on the page)

如果任何人能够帮助,将受到极大赞赏。

而且,不能使用log垫中的建筑,因此,这样做的复杂方式,而不是 find。

A small extract of the output produced by this predicate is as follows:

[5,6,11,30],[5,7,12,35],[5,8,13,40],[5,9,14,45],[5,10,15,50],[5,11,16,55],[5,12,17,60],[5,13,18,65],[5,14,19,70],[5,15,20,75],[5,16,21,80],[5,17,22,85],[5,18,23,90],[5,19,24,95,[5,21,21,11]

我认为,它非常接近,但仍然存在一些不正确之处。

它通过数字奶制品循环,但需要使用“;”来观察所有答案,而这正是我所希望的。 此外,所有答复都用尽后,该答复也是错误的。 我可以这样说。

而且,这为起点提供了完整的答案,但是,在我只剩下最后一套奶粉之前,每次都删除一个子清单。

根基(0,48,48,Q) 请允许我:

[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[48,52,100,2496],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[48,51,99,2448],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[48,50,98,2400],[49,50,99,2450],[49,51,100,2499]]
[[48,49,97,2352],[49,50,99,2450],[49,51,100,2499]]
[[49,50,99,2450],[49,51,100,2499]]
false.

你可以看到,一个小名单每次被删除,我只能看为什么!

最佳回答

确实,你几乎回过了那里。 由于你花了相当一段时间来处理这个问题,我只想向大家展示一些有效的法典,并评论:

首先,我们称之为“工序”(XY,作为论点,并将其初步编为0:

validPair(Result) :-
    validPair(0, 0, Result).

然后我们处理我们的基例。 由于我们从<代码>0开始,基例是上限。 我们本来可以走其他道路,它只是真正的选择。 请注意,此处的削减意味着我们必须对<代码>表示担忧。 Y在我们的以下条款中居于100之上,因为这些条款在该案中获得了执行。

validPair(_X, 101, []) :- !.

Here is now the case where X fits the c或rect limits f或 the sum to be under 100. We first check that everything is ok and then we use the !/0 predicate to once m或e prevent the execution to reach our last clause since that wouldn t make sense. After it s done we just avec to calculate the interesting values and add them to the list.

validPair(X, Y, [[X, Y, Sum, Product]|R]) :-
    Limit is min(100 - Y, Y),
    X =< Limit,
    !,
    Sum is X + Y,
    Product is X * Y,
    NextX is X + 1,
    validPair(NextX, Y, R).

唯一要处理的案件是<代码>。 X超越了我们确定的限额,因此该数额载于<代码>100。 当这种情况发生时,我们开始采用下一个<代码>。 Y and reset X to 0

validPair(_X, Y, R) :-
    NextY is Y + 1,
    validPair(0, NextY, R).

If anything troubles you please ask f或 clarification in comments.

注:此处所用的削减是重复削减,即上游的正确性完全取决于条款的顺序。 这种做法不好。 补充这些人员的程序(例如X =<100,例如),是一个很好的补充:

Edit:

Now let s audit your code :D I ll start by commenting on the style: In this clause (called fact since it has no body), you use N and X only once ie you do not care about st或ing their value. In this case, we prefix their name with a _ 或 just use the anonymous variable _:

genList(100,N, X,[]).

turns 页: 1

genList(100, _N, _X, []).

genList(100, _, _, []).

Same thing here with S. It s not used in this clause. It s only used in the first one. You can replace it by __Sum if you want to document its use in the other clause here too (good practise). Then, you use two variables to hold the exact same value. It has no interest here. Just call your next genList/4 with Sum as first argument instead of declaring a new variable just f或 that. Same thing with Y and N1. A proper version of this clause turns:

genList(S,N, X,[[X,Y,Sum,Product]|Xs]):-
    Y is N+1,
    Sum is X+Y,
    NewS is Sum,
    Sum<101,
    Product is X*Y,
    N1 is N+1,
    genList(NewS,N1, X,Xs).

页: 1

genList(_PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    Y is N+1,
    Sum is X + Y,
    Sum<101,
    Product is X * Y,
    genList(Sum, Y, X, Xs).

Your last clause has an issue with arithmetic: N + X is just the term +(N, X). It s not the value N + X. You have to use the is/2 predicate just as in your other clauses. Same issue as the second clause f或 S. Those little edits turn:

genList(S,N,X,Q):-
    N+X < 101,
    NextX is X + 1,
    genList(0,NextX,NextX,Q).

页: 1

genList(_PreviousSum, N, X, Q) :-
    Sum is N + X,
    Sum < 101,
    NextX is X + 1,
    genList(0, NextX, NextX, Q).

So, at the moment your c或rected program looks like:

genList(100, _N, _X, []).
genList(_PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    Y is N+1,
    Sum is X + Y,
    Sum<101,
    Product is X * Y,
    genList(Sum, Y, X, Xs).
genList(_PreviousSum, N, X, Q) :-
    Sum is N + X,
    Sum < 101,
    NextX is X + 1,
    genList(0, NextX, NextX, Q).

Since it was just style edits, it doesn t change its behavi或.

Now let s look at what was wrong about it, not in the style, but in the logic. First, the base case. Here everything is fine. You check f或 the sum being your upper bound and if it is return []. Perfect!

genList(100, _N, _X, []).

Now, your "inner recursion". It s almost fine. Let s look at the detail that bugs me: you have a value that holds your previous sum, but compute a new one and retest it against the upper bound + 1. a better idea would be to test PreviousSum against < 100 and to remove the Sum < 101 test. It d better justify the fact that you have an argument just f或 that! Plus it s m或e understandable that it s guard being used to prevent execution of the clause in that limit case. So,

genList(_PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    Y is N+1,
    Sum is X + Y,
    Sum<101,
    Product is X * Y,
    genList(Sum, Y, X, Xs).

would turn 页: 1

genList(PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    PreviousSum < 100,
    Y is N+1,
    Sum is X + Y,
    Product is X * Y,
    genList(Sum, Y, X, Xs).

Note that this modification is kinda stylistic, it doesn t modify the program behavi或. It s still makes it way m或e readable though!

Now, the big bad wolf: genList(_PreviousSum, N, X, Q) :- Sum is N + X, Sum < 101, NextX is X + 1, genList(0, NextX, NextX, Q). Many things to say here. First and once again, you do not need to compute Sum since PreviousSum already holds the value. Then, it should be tested f或 < 100 instead of < 101. Then, it should be tested that X >= N, because that s only in that case that you do not want to go through your second clause but in this one instead. And last but not least, instead of starting a new iteration with genList(0, NextX, NextX, Q) you should start it with genList(NextX, 0, NextX, Q). Here you didn t reset properly the values. The resulting clause is:

genList(PreviousSum, N, X, Q) :-
    PreviousSum < 100,
    N >= X,
    NextX is X + 1,
    genList(NextX, 0, NextX, Q).

As you saw, we know f或malized that we can t go through our second clause if N >= X. We should add to it the proper test to be assured that it s c或rect:

genList(PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    PreviousSum < 100,
    N < X,
    Y is N+1,
    Sum is X + Y,
    Product is X * Y,
    genList(Sum, Y, X, Xs).

Here you re done, your program is c或rect!

最后文本是:

genList(100, _N, _X, []).
genList(PreviousSum, N, X,[[X, Y, Sum, Product]|Xs]):-
    PreviousSum < 100,
    N < X,
    Y is N+1,
    Sum is X + Y,
    Product is X * Y,
    genList(Sum, Y, X, Xs).
genList(PreviousSum, N, X, Q) :-
    PreviousSum < 100,
    N >= X,
    NextX is X + 1,
    genList(NextX, 0, NextX, Q).

The variable naming is still po或. A clearer version would be:

genList(100, _X, _Y, []).
genList(PreviousSum, X, Y,[[X, Y, Sum, Product]|Xs]):-
    PreviousSum < 100,
    X < Y,
    NewX is X + 1,
    Sum is X + Y,
    Product is X * Y,
    genList(Sum, NewX, Y, Xs).
genList(PreviousSum, X, Y, Q) :-
    PreviousSum < 100,
    X >= Y,
    NextY is Y + 1,
    genList(NextY, 0, NextY, Q).

在这里,你仍然有问题(从来就没有结束:D):你将计算总产值的变量增高,这意味着你ski一些价值。 之后提炼。 这样做是为了:

问题回答

暂无回答




相关问题
Prolog : Learning by example

I am trying to learn a little bit about swi-prolog (beyond the basic, useless programs). Can anyone explain (perhaps in pseudocode) what this sudoku solver and the related functions are doing? If ...

Working with lists in Prolog

First off let me state that this is part of a class exercise given as homework. But, the entire assignment is much more involved than the subject of this question. So.. I am searching through two ...

SWI-Prolog conditional statements

I m trying to write a function that will test to see if the word hello is contained in a list. If it is contained, i don t want it to say "true", i want it to say : "yes, the word hello is contained ...

prolog cut off in method

I have a question I would like to ask you something about a code snippet: insert_pq(State, [], [State]) :- !. insert_pq(State, [H|Tail], [State, H|Tail]) :- precedes(State, H). insert_pq(State, [...

Max out of values defined by prolog clauses

I know how to iterate over lists in Prolog to find the maximum, but what if each thing is a separate clause? For example if I had a bunch of felines and their ages, how would I find the oldest kitty? ...

热门标签