Help finding paths - search

% link(Origin,Destination,Speed,Length).
link(paris,milano,140,360).
link(paris,london,200,698).
link(berlin,atena,110,714).
link(atena,paris,90,370).
I need to write this route predicate so I get a Path from city X to city Y.
route(Origin,Destination,TrainType,Path,Length,Duration).
I am new to Prolog, so I wrote something like this. I know it's not correct:
route(Origin,Destination,TrainType,Path,Legth,Duration) :-
link(Origin,City,Len),
City \= Origin,
NewLen is Length + Len,
route(City,Destination,TrainType,Path,NewLen,Duration).

Your predicate lacks a base case, that tells it when to stop. Right now, your predicate will always call itself until it fails (or worse, loops indefinitely, depending on your link predicate). The following gives you a reverse path:
route(Goal, Goal, Path, Path). % base case
route(From, To, Path0, Path) :-
direct_link(From, Via),
route(Via, To, [From|Path0], Path).
where a direct link means you can get from A to B; I'm assuming railways are bidirectional:
direct_link(A,B) :- link(A, B, _Speed, _Length).
direct_link(B,A) :- link(B, A, _Speed, _Length).
You will need to call reverse on the path and add arguments to keep track of length and duration. I'll leave that as an exercise.

Related

AQL to validate path to node

We're required to have some AQL that validates a specific path to an entity. The current solution performs very poorly, due to needing to scan whole collections.
e.g. here we have 3 entity 'types': a, b, c (though they are all in a single collection) and specific edge collections between them and we want to establish whether or not there is a connection between _key "123" and _key "234" that goes exactly through a -> b -> c.
FOR a IN entities FILTER e._key == "123"
FOR b IN 1..1 OUTBOUND e edges_a_to_b
FOR c IN 1..1 INBOUND e_1 edges_c_to_b
FILTER e_2._key == "234"
...
This can fan out very quickly!
We have another solution, where we use SHORTEST PATH and specify the appropriate DIRECTION and edge collections which is much faster (>100times). But worry that this approach does not satisfy quite our general case... the order of the edges is not enforced, and we may have to go through the same edge collection more than once, which we cannot do with that syntax.
Is there another way, possibly involving paths in the traversal?
Thanks!
Dan.
If i understand correctly you always know the exact path that is required between your two vertices.
So to take your example a -> b -> c, a valid result will have:
path.vertices == [a, b, c]
So we can use this path to filter on it, which only works if you use a single traversal step instead of multiple ones.
So what we try to du is the following pattern:
FOR c,e, path IN <pathlength> <direction> <start> <edge-collections>
FILTER path.vertices[0] == a // This needs to be formulated correctly
FILTER path.vertices[1] == b // This needs to be formulated correctly
FILTER path.vertices[2] == c // This needs to be formulated correctly
LIMIT 1 // We only net exactly one path, so limit 1 is enough
[...]
So with this hint is it possible to write the query in the following way:
FOR a IN entities
FILTER a._key == "123"
FOR c, e, path IN 2 OUTBOUND a edges_a_to_b, INBOUND edges_b_to_c
FILTER path.vertices[1] == /* whatever identifies b e.g. vertices[1].type == "b" */
FILTER path.vertices[2]._key == "234"
LIMIT 1 /* This will stop as soon as the first match is found, so very important! */
/* [...] */
This will allow the optimizer to apply the filter conditions as early as possible, und will (almost) use the same algorithm as the shortest path implementation.
The trick is to use one traversal instead of multiples to save internal overhead and allow for better optimization.
Also take into account that it might be better to search in the opposite direction:
e.g. instead of a -> b -> c check for c <- b <- a which might be faster.
This depends on the amount of edges per each node.
I assume a doctor has many surgeries, but a single patient most likely has only a small amount of surgeries so it is better to start at the patient and check backwards instead of starting at the doctor and check forwards.
Please let me know it this helps already, otherwise we can talk about more details and see if we can find some further optimizations.
Disclaimer: I am part of the Core-Dev team at ArangoDB

Length error while creating a dfn function in APL to check for anagrams

I am a beginner in APL and am writing a dfm function to check whether two strings are an anagram of one another. The method I thought of was:
{⍵[⍋⍵] ≡ ⍺[⍋⍺]}
However, it returns 0 for 'ALBERT EINSTEIN' and 'TEN ELITE BRAINS' that are anagrams. I tried to check why:
a ← 'ALBERT EINSTEIN'
b ← 'TEN ELITE BRAINS'
a[⍋a] ≡ b[⍋b]
0
a[⍋a]
ABEEEIILNNRSTT
b[⍋b]
ABEEEIILNNRSTT
a[⍋a] = b[⍋b]
LENGTH ERROR
a[⍋a]=b[⍋b]
Is it because the second rearrangement seems to have a leading space? Why does that happen? Can anyone suggest a way I can make this program work?
In your specific case, you would need to filter out the spaces from the vectors you're comparing. This is because your vectors will have different lengths after grading up, since one of them has an extra space.
One solution could be:
'albert einstein'{(a b)←(⍺~' ')(⍵~' ')⋄a[⍋a]≡b[⍋b]}'ten elite brains'
The first part of the code, (a b)←(⍺~' ')(⍵~' '), assigns ⍺ and ⍵, without spaces (~' '), to a and b respectively. Then, you can just compare the vectors the same way you're doing now.
You can check the output of the code above on Try it online!

When searching, Prolog gives correct answers but repeats them N times before searching another

Ok So i've got this Prolog code that represents an evolving world of blocks, and there's a robotic arm that can move 1 block at the time, and 2 little robots "rob and bor" that can paint blocks of their assigned color when the blocks are on top of a tower or on the bottom of a tower (See code for the conditions). function clear(X) is true when block X is on top of a tower, and ontable(X) is true when X is on the table (at the bottom of a tower). Single block towers return both clear and ontable as true.
The code aims to give all the solutions, step by step, when asked for a particular state (Like all 4 blocks on a single tower and red painted).
For that, there's a set of actions and facts defined, their conditioning effects (When action A is done under conditions C, what happens to the fact F) and a possibility/reality check with functions poss(returns true if some action is possible to do) and holds(returns true if some fact is true) that work on every state S. legal is the mix of these 2(Something is legal if everything in it holds and is possible).
%% Object Declaration (problem-specific)
block(B) :- member(B,[a,b,c,d]).
% colors available for rob and bor
color(rob,B) :- member(B,[blue]).
color(bor,B) :- member(B,[red]).
%% Initial Situation (problem-specific)
holds(F,s0) :- member(F,[on(a,b),on(b,c),ontable(c), ontable(d), clear(a), clear(d)]).
holds(color(B,white),s0) :- block(B).
%% Blocks World Preconditions (domain-specific)
%% action move_to_block(X,Z) moves block X on top of block Z
% poss is true when its possible to do the action.
poss(move_to_block(X,Z),S) :-
holds(clear(X),S), holds(clear(Z),S), Z\=X, \+ holds(on(X,Z),S).
poss(move_to_table(X),S) :-
holds(clear(X),S), \+ holds(ontable(X),S).
%% Robot R paints block B of color C
poss(paint(rob,B,C),S) :-
color(rob,C),holds(clear(B),S), \+ holds(color(B,C),S).
poss(paint(bor,B,C),S) :-
color(bor,C), holds(ontable(B),S), \+ holds(color(B,C),S).
%% Blocks World Effects (domain-specific)
% is_conditional_negative_effect(Act,Cond,Fact)
% when Act is peformed and Cond holds, Fact becomes false
is_conditional_negative_effect(move_to_block(X,_),on(X,Y),on(X,Y)).
is_conditional_negative_effect(move_to_block(X,_),ontable(X),ontable(X))
is_conditional_negative_effect(move_to_block(X,Z),true,clear(Z)).
is_conditional_negative_effect(move_to_table(X),on(X,_),on(X,_)).
is_conditional_negative_effect(paint(R,B,C),color(B,D),color(B,D)).
% is_conditional_positive_effect(Act,Cond,Fact)
% when Act is peformed and Cond holds, Fact becomes true
is_conditional_positive_effect(move_to_block(X,_),on(X,Y),clear(Y)).
is_conditional_positive_effect(move_to_block(X,Z),true ,on(X,Z)).
is_conditional_positive_effect(move_to_block(X,_),true,clear(X)).
is_conditional_positive_effect(move_to_table(X),true ,ontable(X)).
is_conditional_positive_effect(move_to_table(X),on(X,Y),clear(Y)).
is_conditional_positive_effect(move_to_table(X),true,clear(X)).
is_conditional_positive_effect(paint(R,B,C),color(B,_),color(B,C)).
holds(true,s0). % "true" always holds
holds(F,do(A,S)) :-
holds(F,S),
\+ (is_conditional_negative_effect(A,C,F), holds(C,S)).
holds(F,do(A,S)) :-
is_conditional_positive_effect(A,C,F),holds(C,S).
% S is legal if it is the result of performing executable actions
legal(s0).
legal(do(A,S)) :-
legal(S),
poss(A,S).
So thing is, when a consult done like follows ( time() only makes that the given answer returns the process time, for optimization sake... that's another problem i'll check later):
time((legal(S), holds(on(b,d),S), holds(on(c,b),S), holds(on(a,c),S), holds(color(b,blue),S), holds(color(a,red),S))).
SO far I get correct answers, but repeated like 10 times before it gives another, (correct too), so if I want all the answers, I've got to smash the ; like ten thousand times. I've been approximately 3 hours trying to solve this issue, since it doesn't let me check if I get all the correct answers or something is missing. Do you guys figure out what's going on?.
Tried to make everything as clear as possible, but comment if you need me to clarify something!
Finally, with a friend, we managed to fix it, the problem was on the positive conditional effects, specifically those related to clear. These affirmations were obvious, since a block must already return true to clear before being moved:
is_conditional_positive_effect(move_to_block(X,_),true,clear(X)).
is_conditional_positive_effect(move_to_table(X),true,clear(X)).
Also I changed some conditionals to be more specific, these greately improved the performance of the search:
is_conditional_negative_effect(move_to_table(X),on(X,_),on(X,_)).
was replaced by
is_conditional_negative_effect(move_to_table(X),on(X,Y),on(X,Y)).
and
is_conditional_positive_effect(paint(R,B,C),color(B,_),color(B,C)).
was replaced by
is_conditional_positive_effect(paint(R,B,C),true,color(B,C)).
Credits to my mate Pablo.

R: agrep error when replacing string with another string

after a lot of trial/error and the search function I am still somewhat clueless about an I-thought-simple-thing (as always, hrmpf):
I have a column in a data frame x$question and within that column, there is an expression 'A/V' every once in a while, and I simply want it to be changed to 'A / B'.
I tried a little here and there, and thought this should work:
x$question[agrep('A/V',x$question)]<-'A / B'
but I get the error:
In `[<-.factor`(`*tmp*`, agrep('A/V', :
invalid factor level, NAs generated
or I could do this
agrep('A/V','A / B', x$question).
But here I get the error:
Error in .amatch_bounds(max.distance) :
match distance components must be non-negative
Since I am quite out of ideas, I would be very thankful, if you had a suggestions, or maybe an even simpler way of replacing a string with another string.
Does this work?
gsub("A/V","A/B",x$question)
Example:
x<-c("A/V", "A/V", "A/V")
x<-gsub("A/V","A/B",x)
>x
[1] "A/B" "A/B" "A/B"
Note: You can use ifelse for that too.
> ifelse(x=="A/B","A/V",x)
[1] "A/V" "A/V" "A/V"

Regular expression for strings with even number of a's and odd no of b's

Im having a problem in solving the problem:-
Its an assignment, i solved it, but it seems to be too long and vague, Can anyboby help me please......
Regular expression for the strings with even number of a's and odd number of b's where the character set={a,b}.
One way to do this is to pass it through two regular expressions making sure they both match (assuming you want to use regular expressions at all, see below for an alternative):
^b*(ab*ab*)*$
^a*ba*(ba*ba*)*$
Anything else (and, in fact, even that) is most likely just an attempt to be clever, one that's generally a massive failure.
The first regular expression ensures there are an even number of a with b anywhere in the mix (before, after and in between).
The second is similar but ensures that there's an odd number of b by virtue of the starting a*ba*.
A far better way to do it is to ignore regular expressions altogether and simply run through the string as follows:
def isValid(s):
set evenA to true
set oddB to false
for c as each character in s:
if c is 'a':
set evenA to not evenA
else if c is 'b':
set oddB to not oddB
else:
return false
return evenA and oddB
Though regular expressions are a wonderful tool, they're not suited for everything and they become far less useful as their readability and maintainability degrades.
For what it's worth, a single-regex answer is:
(aa|bb|(ab|ba)(aa|bb)*(ba|ab))*(b|(ab|ba)(bb|aa)*a)
but, if I caught anyone on my team actually using a monstrosity like that, they'd be sent back to do it again.
This comes from a paper by one Greg Bacon. See here for the actual inner workings.
Even-Even = (aa+bb+(ab+ba)(aa+bb)*(ab+ba))*
(Even-Even has even number of Aas and b's both)
Even a's and odd b's = Even-Even b Even-Even
This hsould work
This regular expression takes all strings with even number of a's and even number of b's
r1=((ab+ba)(aa+bb)*(ab+ba)+(aa+bb))*
Now to get regular expression for even a's and odd b's
r2=(b+a(aa+bb)*(ab+ba))((ab+ba)(aa+bb)*(ab+ba)+(aa+bb))*
(bb)*a(aa)*ab(bb)*
ab(bb)* a(aa)*
b(aa)*(bb)*
.
.
.
.
.
.
there can be many such regular expressions. Do you have any other condition like "starting with a" or something of the kind (other than odd 'b' and even 'a') ?
For even number of a's and b's , we have regex:
E = { (ab + ba) (aa+bb)* (ab+ba) }*
For even number of a's and odd number of b's , all we need to do is to add an extra b in the above expression E.
The required regex will be:
E = { ((ab + ba) (aa+bb)* (ab+ba))* b ((ab + ba) (aa+bb)* (ab+ba))* }
I would do as follows:
regex even matches the symbol a, then a sequence of b's, then the symbol a again, then another sequence of b's, such that there is an even number of b's:
even -> (a (bb)* a (bb)* | a b (bb)* a b (bb)*)
regex odd does the same with an odd total number of b's:
odd -> (a b (bb)* a (bb)* | a (bb)* a b (bb)*)
A string of even number of a's and odd number of b's either:
starts with an odd number of b's, and is followed by an even number of odd patterns amongst even patterns;
or starts with an even number of b's, and is followed by an odd number of odd patterns amongst even patterns.
Note that even has no incidence on the evenness/oddness of the a/b's in the string.
regex ->
(
b (bb)* even* (odd even* odd)* even*
|
(bb)* even* odd even* (odd even* odd)* even*
)
Of course one can replace every occurence of even and odd in the final regex to get a single regex.
It is easy to see that a string satisfying this regex will indeed have an even number of a's (as symbol a occurs only in even and odd subregexes, and these each use exactly two a's) and an odd number of b's (first case : 1 b + even number of b's + even number of odd; second case : even number of b's + odd number of odd).
A string with an even number of a's and an odd number of b's will satisfy this regex as it starts with zero or more b's, then is followed by [one a, zero or more b's, one more a and zero or more b's], zero or more times.
A high-level advice: construct a deterministic finite automaton for the language---very easy, encode parity of the number of as and bs in the states, with q0 encoding even nr. of as and even nr. of bs, and transition accordingly---, and then convert the DFA into a regular expression (either by using well-known algorithms for this or "from scratch").
The idea here is to exploit the well-understood equivalence between the DFA (an algorithmic description of regular languages) and the regular expressions (an algebraic description of regular languages).
The regular expression are given below :
(aa|bb)*((ab|ba)(aa|bb)*(ab|ba)(aa|bb)*b)*
The structured way to do it is to make one transition diagram and build the regular expression from it.
The regex in this case will be
(a((b(aa)*b)*a+b(aa)*ab)+b((a(bb)*a)*b+a(bb)*ba))b(a(bb)*a)*
It looks complicated but it covers all possible cases that may arise.
the answer is (aa+ab+ba+bb)* b (aa+ab+ba+bb)*
(bb)* b (aa)* + (aa)* b (bb)*
This is the answer which handles all kind of strings with odd b's and even a's.
If it is even number of a's followed by odd number of b's
(aa)*b(bb)* should work
if it is in any order
(aa)*b(bb)* + b(bb)(aa) should work
All strings that have even no of a's and odd no of b's
(((aa+bb) * b(aa+bb) * ) + (A +((a+b)b(a+b)) *)) *
here A is for null string. A can be neglected.
if there is any error plz point it out.

Resources