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.
Related
:- dynamic flat/3.
addr('Nollendorfstr',5).
addr('Nollendorfstr',14).
addr('Nollendorfstr',18).
addr('Maxplanckstr',2).
flat([16,12,4],400.35, addr('Nollendorfstr',14)).
flat([14,13,4],380.00, addr('Nollendorfstr',18)).
flat([20,18,4,5],650.80, addr('Nollendorfstr',5)).
flat([9,17,19,20],870.70, addr('Maxplanckstr',2)).
We have for each flat three arguments. So flat(array of rooms, price, address).
changeprice(Street):-
retract(flat(Rooms,Price,addr(Street,Num))),
Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num))).
I'd like to change the price for all flats which are in this street.
so when I put there changeprice('Nollendorfstr').
It will just change one of them.
How can I change all of them?
You can use either a failure-driven loop (which gets its name from the use of explicit failure after processing an item to backtrack into processing the next item):
changeprice(Street) :-
retract(flat(Rooms,Price,addr(Street,Num))),
Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num))),
fail.
changeprice(_).
Or the de facto standard forall/2 meta-predicate (where the first argument can be interpreted as a generator of candidate solutions that are verified by the second argument, the test part):
changeprice(Street) :-
forall(
retract(flat(Rooms,Price,addr(Street,Num))),
( Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num)))
)
).
In this particular case, both solutions are equivalent. But note that failure-driven loops and forall/2 calls have different semantics. A failure-driven loop can mask an unexpected failure. But a forall/2 call will fail instead of succeeding if the second argument fails.
Using the + function on a tuple of two Int64s returns the sum:
julia> +((1, 2))
3
However, using the + function on a variable that references a tuple gives the following error:
julia> a = (1, 2)
(1,2)
julia> +(a)
ERROR: MethodError: no method matching +(::Tuple{Int64, Int64})
I'm having trouble understanding why it behaves like this, especially when the following code returns true.
julia> typeof(a) == typeof((1, 2))
Note that, contrary to what you might think,
julia> :(+((1, 2)))
:(1 + 2)
This is a single function call equivalent to (+)(1, 2). There is no tuple, although the syntax may look like there is a tuple. (The + function, as you noted, does not work on tuples.) Is this behavior desirable? Well it was reported as a bug #12755, but then fixed. But the fix caused bug #12771 which resulted in the fix being reverted by pull #12772.
The solution to this mess is to avoid calling operators as functions without explicitly writing parentheses. That is, always write (+)(1, 2) instead of +(1, 2). You can verify that (+)((1, 2)) throws the error that you expect.
(This problem only occurs with unary operators, hence why | and * are not subject to it.)
If you're interested, the heart of this problem is a fundamental ambiguity between +(x, y) function call syntax and unary operator syntax. Here are a few situations that motivate parsing + and - as unary operators, even when followed by (:
In -(x+y)^2, it is highly likely that (-)((x+y)^2) was meant, not ((-)(x+y))^2. So we cannot simply unconditionally parse -( as a function call.
Instead what must be done is the thing after - parsed up to a certain precedence, so that -x * y is parsed as (-x) * y, -x + y as (-x) + y, but -x^y as -(x^y).
Exception: But this would make -(1, 2) parse as (-)((1, 2)), that is, a function called on a tuple. For whatever reason or another, it was decided to add an exception for when the thing after - looks like a function call tuple. This is so that +(1, 2) would work, but this is really mostly just a hack.
But from the parser's perspective, ((1, 2)) looks exactly like (1, 2); just the former is wrapped in parentheses.
My personal opinion is that the -(1, 2) notation is silly (and doesn't work in all cases anyway; e.g. in -(1, 2)^2). If that exception weren't around, and -(1, 2) consistently parsed as a unary function call on a tuple, then more consistency could be had without (I think) much loss. It's not too bad to just write 1 - 2 or (-)(1, 2) when a binary function call is desired.
Is there any way that
PadRight[a \[PlusMinus] b,2,""]
Returns
{a \[PlusMinus] b,""}
Instead of
a \[PlusMinus] b \[PlusMinus] ""
?
I believe that i need to somehow deactivate the operator properties of [PlusMinus].
Why do i need this?
I'm creating a program to display tables with physical quantities. To me, that means tables with entries like
(value of a) [PlusMinus] (uncertainty of a)
When i have several columns with different heights, i'm stuffing the shorter ones with "", so i can use Transpose the numeric part of the table.
If the column has more than one entrie, there's no problem:
PadRight[{a \[PlusMinus] b,c \[PlusMinus] d},4,""]
gives what i want:
{a \[PlusMinus] b,c \[PlusMinus] d,"",""}
It is when the column has only one entrie that my problem appears.
This is the code that constructs the body stuffed with "":
If[tested[Sbody],1,
body = PadRight[body, {Length[a], Max[Map[Length, body]]
With
tested[a__] :=
If[Length[DeleteDuplicates[Map[Dimensions, {a}]]] != 1, False,
True];
, a function that discovers if is arguments have the same dimension
and
a={Quantity1,Quantity2,...}
Where the quantities are the one's that i want on my table.
Thanks
First you need to be aware of that any expression in Mathematica is in the form of Head[Body]
where body may be empty, a single expression or a sequence of expressions separated by commas
Length operate on expressions, not necessarily lists
so
Length[PlusMinus[a,b]]
returns 2 since the body of the expression contains to expressions (atoms in this case) that are a and b
Read the documentation on PadRight. The second argument define the final length of the expression
so
PadRight[{a,b},4,c] results with a list of length 4 with the last two elements equal to
PadRight[{a,b},2,c] results with the original list since it is already of length 2
Therefore
PadRight[PlusMinus[a,b],2,anything] just returns the same PlusMinus[a,b] unchanged since it is already of length 2
so, youר first example is wrong. You are not able to get a result with head List using PadRight when you try to pad to an expression with head PlusMinus
There is no problem of executing
PadRight[PlusMinus[a,b],3,""]
but the result looks funny (at best) and logically meaningless, but if this is what you wanted in the first place you get it, and following my explanations above you can figure out why
HTH
best
yehuda
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).
Why isn't t:insert(9) working in Lua?
(I want to append a value of 9 to the end of the table)
t = {1,2,3}
table.insert(t, 9) -- works (appends 9 to end of table t)
t:insert(9) -- does NOT work
I thought in general
a.f(a,x) is equalivant to a:f(x) in Lua
While it's true that a:f(x) is simply syntactic sugar for a.f(a,x) that second syntax is not what you have there. Think it through backwards:
The function call you tried is t:insert(9)
So the syntax rule you stated would be t.insert(t, 9)
But the working function call is table.insert(t, 9)
See how the last two aren't the same? So the answer to your question is that insert() isn't a function contained in t, it's in "table".
Since the table methods haven't been associated with t, you either have to call them directly through the table.insert syntax, or define the metatable on t to be table, e.g.:
> t = {1,2,3}
> setmetatable(t, {__index=table})
> t:insert(9)
> print (t[4])
9
You're trying to call an entry in your table called insert, however, in table t, there is none. If you want it to work, what you could do is to set the insert entry to table.insert
t = {insert = table.insert, 1, 2, 3}
t:insert(9)
print(t[4]) -- 9, as you'd expect