recursion in prolog - error in base case - prolog

I'm trying to write predicate range\3 that takes three parameters the first is the start, the second is the end and return the generated list in the third argument.
E.g rang(1,5,L).
L = [1, 2, 3, 4, 5]
I used this code
range(E,E,[E]).
range(S,E,L):-
S1 is S + 1,
range(S1,E,[S|L]).
But it does not work, when i used trace command to know where is the error i recognized that the base case is useless, I also tried the green cut !in the base case but it does not work range(E,E,[E]),!.
So, if any one knows what is the problem please help me

You're building the list in 'wrong' sense. Consider that when you'll call the base case, it will receive the consed list. How could match a single element list ? Try instead
range(S,E,[S|L]):-
S1 is S + 1,
range(S1,E,L).

Related

Creating a counter Prolog

I'm trying to make a counter out of the following code:
contador([], 0,[]).
contador([via(A,_,_)|R], Tot,Regiao):-
cidade(A,_,_,Reg1),Reg1==Regiao,
Tr is Tot + 1,
contador(R,Tr,Regiao).
Given my list's format and cidade:
L=[via(porto,lisboa,_),via(braga,faro,_),via(guimaraes,santarem,_)]
cidade(lisboa,_,_,A)
Why isn't it working?
cidade(porto,portugal,40,litoral).
cidade(braga,portugal,350,interior).
cidade(guimares,portugal,40,litoral).
cidade(alverca,portugal,30,valedotejo).
cidade(santarem,portugal,25,valedotejo).
cidade(faro,portugal,20,litoral).
cidade(sevilha,espanha,60,interior).
With this list:
A = [via(porto, braga, 5), via(braga, guimaraes, 9), via(guimaraes, alverca, 7), via(alverca, faro, 10)] ;
I'm trying to do the following:
?-contador(A,Tot,litoral).
false.
My objective is to count the cities that have A(cidades(_,_,_,A)) as a parameter.
There are several issues in the code you presented.
1)
First, a remark, in Prolog, "=" is not an assignment like in C/C++ and other imperative languages. That means you can not type:
A=[...].
contador(...).
but use a single query:
A=[...],contador(...).
2)
These two statements are possibly an error:
contador([], 0,[]).
contador([via(A,_,_)|R], Tot,Regiao):-...
because third argument is in the first one a list, and is not in the second.
3)
Finally, what you call a "contador/counter" ( and that is, probably, better called an "accumulator" ) is not correctly "finished". When the original list is exhausted, the statement:
contador([], 0,[]).
is applied, but this statement request counter equal to cero. Probably, it will be better something like:
contador([], R, _) :- ... /* do something with R */
4)
These two statements:
cidade(A,_,_,Reg1),Reg1==Regiao,
can be unified in a single one:
cidade(A,_,_,Regiao),
5)
In general, try to skip "is" operator. By example, replace:
Tr is Tot + 1,
with:
succ(Tot,Tr),
6)
If statement:
cidade(A,_,_,Reg1),Reg1==Regiao,
fails, you have not an alternative rule.

dont know how to unificate this in prolog

Hi if i have the next knowladge base
natural(0).
natural(suc(X)):-natural(X).
sum(0,N,N).
sum(suc(N),suc(N),R).
mult(N,1,N).
mult(number,times,result):-mult(number,times-1,partial), sum(partial,number,result).
and i ask the query ? mult(5,3,15).
how does prolog runs this??? first i instanciate number to 5, times to 3, and 5 to result. And after it unificates with the head of the query, how does works with the body of the clause, specially what value would partial take

Delete an unassigned member in list

i write a code , to get some specific output (2 List) , and it's work , and give me what i need , but there are unassigned element in the two list ,as shown below ,so my question is : how to delete thess unassigned elements .
Courses = [_G1619, linear, _G1607, physics2, physics1, calculas1|_G1590],
Marks = [_G1622, 78, _G1610, 90, 80, 78|_G1593]
In SWI-Prolog there are some list processing utilities like exclude/3, that allow to specify a predicate to be used on each element. var/1 seems appropriate. For instance
2 ?- exclude(var,[1,A,B,2,3|L],R).
L = [],
R = [1, 2, 3] ;
...
(note: place a cut after the call to get rid of nondeterminism).
I was surprised to find it also removed the unbounded tail - I thought it would require a proper list. Then it should fit your request.

Erlang binary matching efficiency

What would be the difference between matching like:
fun(Binary) ->
[Value, Rest] = binary:split(Binary, <<101>>)
end
and
fun(Binary) ->
[Value, <<Rest/binary>>] = binary:split(Binary, <<101>>)
end
I am thinking that one may simply increment a counter as it traverses the binary and keep the sub binary pointer and the other will copy a new binary. Any ideas?
I can think of pattern matching in two ways.
Method 1:
[A,B] = [<<"abcd">>,<<"fghi">>]
Method 2:
[A, <<B/binary>>] = [<<"abcd">>,<<"fghi">>]
Unless you need to make it sure B is binary, Method 2 will take it longer, few micro seconds, because it's not just assigning <<"fghi">> to B, but also make it sure it is bianary.
However if you need more parsing than method 2, you can go further, which method 1 can't do.
[A, <<B:8, Rest/binary>>] = [<<"abcd">>,<<"fghi">>].
I think you could test it by timer module's tc/N function.

Mocking Sort With Mocha

How can I mock an array's sort expect a lambda expression?
This is a trivial example of my problem:
# initializing the data
l = lambda { |a,b| a <=> b }
array = [ 1, 2, 3, 4, 5 ]
sorted_array = [ 2, 3, 8, 9, 1]
# I expect that sort will be called using the lambda as a parameter
array.expects(:sort).with( l ).returns( sorted_array )
# perform the sort using the lambda expression
temp = array.sort{|a,b| l.call(a,b) }
Now, at first I expected that this would work; however, I got the following error:
- expected exactly once, not yet invoked: [ 1, 2, 3, 4, 5 ].sort(#<Proc:0xb665eb48>)
I realize that this will not work because l is not passed as a parameter to l. However, is there another way to do what this code is trying to accomplish?
NOTE: I have figured out how to solve my issue without figuring out how to do the above. I will leave this open just in case someone else has a similar problem.
Cheers,
Joseph
Mocking methods with blocks can be quite confusing. One of the keys is to be clear about what behaviour you want to test. I can't tell from your sample code exactly what it is that you want to test. However, you might find the documentation for Mocha::Expectation#yields (or even Mocha::Expectation#multiple_yields) useful.

Resources