how does prolog loop through this code - loops

How does this code work? I wold have tough it worked for the first possible values of C and X, but somehow it loops.
path(A, B, [A, B], X) :-
route(A, B, X).
path(A, B, PathAB, Length) :-
route(A, C, X),
path(C, B, PathCB, LengthCB),
PathAB = [A | PathCB],
Length is X + LengthCB.
there are routes defind as route(bahirdar, mota, 32)..

Taking a simpler example, suppose you have the following facts:
foo(1).
foo(2).
Then you query:
| ?- foo(X).
Prolog will succeed with X = 1 and prompt:
X = 1 ?
The ? indicates that there was a choice point (it found additional options to explore for foo), and if you press ; and Enter, it will backtrack and try to find another solution, which it does, and prompts:
X = 2 ?
Now if you press ; and Enter it will fail and stop because it can't succeed any further.
Let's try something a little more elaborate with a conjunction. Use the facts:
foo(1).
foo(2).
foo(3).
And the rule:
odd(X) :- X /\ 1 =:= 1. % X is odd if X bit-wise and with 1 is 1
And then do a query that says I want X to be foo and I want X to be odd:
| ?- foo(X), odd(X).
X = 1 ? ;
X = 3 ? ;
no
| ?-
Note that we only get the odd solutions. What happens in this query is as follows:
Prolog calls foo(X) and succeeds with X = 1.
Prolog calls odd(1) (since X is instantiated as 1) and succeeds
Prolog shows the result X = 1.
The user indicates a backtrack is desired (find more solutions)
Prolog backtracks to odd(1), which has no variables to reinstantiate, so Prolog backtracks further
Prolog backtracks to foo(X) and succeeds with X = 2 and proceeds ahead again
Prolog calls odd(2) and fails. The failure causes Prolog to backtrack to the foo call
Prolog backtracks to foo(X) and succeeds with X = 3 and proceeds ahead again
Prolog calls odd(3) and succeeds and displays the solution X = 3<
...
Apply this now to your predicate:
path(A, B, [A, B], X) :-
route(A, B, X).
path(A, B, PathAB, Length) :-
route(A, C, X),
path(C, B, PathCB, LengthCB),
PathAB = [A | PathCB],
Length is X + LengthCB.
If a query is made to path, Prolog first attempts to match the query to the head of the first clause path(A, B, [A, B], X). A match to this head would mean that the 3rd argument would have to be a list consisting of exactly 2 elements. If there's a match, Prolog will call route(A, B, X). If route(A, B, X) succeeds, Prolog will display the values of A, B, and X that resulted in the success. If the user prompts for more solutions, Prolog will backtrack which would either (a) call route(A, B, X) again if there was a choice point left in the prior call, or (b) backtrack further and attempt to match the original call to path to the second clause, path(A, B, PathAB, Length). Similarly, if the original call to route(A, B, X) had failed, Prolog would backtrack to attempt to match the second clause.
If executing the second clause, you have the conjunction case like shown in the prior simplified example. Here, it's conjunctive sequence of four calls starting with route(A, C, X). Prolog will attempt each of these calls in sequence and move to the next as long as the prior succeeds. When a failure is encountered, Prolog will backtrack to the prior call and, if there was a choice point, attempt a reinstantiation of arguments to make the prior call succeed again, etc.
Perhaps you can see how this is different than looping. In a typical imperative language, you might have a loop consisting of the following statements:
while (something) do
A
B
C
end
Which would execute as A B C A B C A B C ... until the loop condition is met. In Prolog, you might have:
A,
B,
C,
Which may execute as: A(succeeds) B(fails - backtrack) A(succeeds) B(fails - backtrack) A(succeeds) B(succeeds) C(fails - backtrack) B(succeeds) C(succeeds) and then finally yield results.
If this were a really good answer, I'd include a bunch of diagrams to illustrate this. But I hope the description helps enough. :)

Related

Making a recursive call from the loop macro

I'm pretty new to common lisp and I've been stuck on a particular problem. The function I'm suppose to write takes in two parameters: a function and a List. It iterates through the list and calls the given function on each element in the list. If the function returns true then the element is added to a sub list that is returned
What I've tried so far is:
(defun myFunc(f l)
(loop for x in l
if (listp x) do (myFunc f x)
else if (eql t (funcall f x))
collect x
)
)
The function I've been given for f takes a parameter and if it's is an number, returns true. So far my code works if aList is a simple list such as (1 2 3). However when I input a nested list like (1 2 (4 5) 7) only (1 2 7) is outputted rather than (1 2 (4 5) 7).
I'm assuming it has something to do with my recursive call and what is returning. Would really appreciate some help on this
There are a couple of minor issues. First off, I assume it's just a typo, but you need to replace aFunc with f (as there's no variable aFunc in your code).
Now to the main point of the question. In your else if branch, you correctly collect the value when the predicate is true. But in your recursive case, you simply run some code and discard the result. You're going to want to collect there too.
(defun myFunc (f l)
(loop for x in l
if (listp x)
collect (myFunc f x)
else if (eql t (funcall f x))
collect x))
Finally, just a style note. It's generally more idiomatic to treat a predicate as true if it returns anything truthy, not just t. So if I was writing this, I'd probably replace (eql t (funcall f x)) with simply (funcall f x). If this is a homework assignment and the teacher told you to do it the other way, stick with that. But if it's for your benefit, you may consider changing that as well.

How to prevent recursion after looping once

I just realized that was a dumb question. Curious if anyone can still find a loophole though.
Source code:
married(trump,obama).
married(trump,goat).
married(pepee,pepper).
married(X,Y) :- married(Y,X),!. % not awesome because of infinite recursion
Goal: ex. married(trump, putin).
trace(
first base case fails.
second base case fails.
third base case fails.
married(trump,putin) = married(putin,trump),!.
what I want it doing is try married (putin,trump) again but all earlier base cases will fail again. We tried switching args before and failed. So don't recurse. Just return false.
I get a stack error because until married(putin,trump) or other way around before ! will never return true or false so cut will not be able triggered.
Easier and more sane way is to just rewrite the code to prevent recursion. I'm curious if there is a way to try switching args once and return fail if that fails. If u have a long list of facts, u can reduce that long list by half if u can try arg1,arg2 and vice versa. Potentially more exponentially if we get crazy permutation scenarios.
Any insights will be awesome thanks.
You are on the right track with "switching args once and return fail if that fails", even though that is worded very imperatively and does not cover all modes we expect from such a relation.
For this to work, you need to separate this into two predicates. It is easy to show that a single predicate with the given interface is not sufficient.
First, the auxiliary predicate:
married_(a, b).
married_(c, d).
etc.
Then, the main predicate, essentially as you suggest:
married(X, Y) :- married_(X, Y).
married(X, Y) :- married_(Y, X).
Adding impurities to your solution makes matters worse: Almost invariably, you will destroy the generality of your relations, raising the question why you are using a declarative language at all.
Example query:
?- married(X, Y).
X = a,
Y = b ;
X = c,
Y = d ;
X = b,
Y = a ;
X = d,
Y = c.
Strictly speaking, you can of course also do this with only a single predicate, but you need to carry around additional information if you do it this way.
For example:
married(_, a, b).
married(_, c, d).
married(first, X, Y) :- married(second, Y, X).
Example query:
?- married(_, X, Y).
X = a,
Y = b ;
X = c,
Y = d ;
X = b,
Y = a ;
X = d,
Y = c.
This closely follows the approach you describe: "We tried switching args before. So don't do it again."

Plese write a solution for a prolog task

I have a matrix M x N, I need to switch places of the elements with indexed [1,N] and [M,N].
Update
I am really new to Prolog, here is my solution that returns false :(
main([FirstRow|Tail],X):-
last(FirstRow, A),
last(Tail, LastRow),
last(LastRow, B),
skipLastItem(FirstRow,FirstRowWithoutA),
skipLastItem(LastRow,LastRowWithoutB),
append(FirstRowWithoutA,[B],FirstRowNew),
append(LastRowWithoutB,[A],LastRowNew),
assign([FirstRowNew],X),
skipLastItem(Tail,Middle),
appendAllElements(Middle,X),
append(X,LastRowNew,X).
appendAllElements([X|Tail],List):-
append(List,X,NewList),
appendAllElements(Tail,NewList).
appendAllElements([],_).
assign(Item,Item).
skipLastItem([_],[ ]) :- !.
skipLastItem([H|T],[H|S]) :-
skipLastItem(T,S).
This sounds like homework, so I'm going to be a bit vague here...
Start with the simpler problem of replacing one value in a list. Write a recursive predicate
swap_list(X,N,A,B,Y)
which should be read as "for a list X, at position N, removing the value A and replacing it with B gives the list Y".
Now we can extend this to the case of matrices. Write a second recursive predicate
swap_matrix(X,M,N,A,B,Y)
which should be read as "for a matrix X, at position (M,N), removing element A and replacing it with B gives the matrix Y". The base case of this recursion, where M=0, will contain a call to swap_list.
Now, you can swap two positions (M1,N1) and (M2,N2) with the following:
swap(X,M1,N1,M2,N2,Y) :-
swap_matrix(X,M1,N1,A,B,Z),
swap_matrix(Z,M2,N2,B,A,Y).
Note that we insert B into the matrix Z before we even know what it is - B isn't assigned a value until the second swap_matrix call.

Iterating with respect to two variables in haskell

OK, continuing with my solving of the problems on Project Euler, I am still beginning to learn Haskell and programming in general.
I need to find the lowest number divisible by the numbers 1:20
So I started with:
divides :: Int -> Int -> Bool
divides d n = rem n d == 0
divise n a | divides n a == 0 = n : divise n (a+1)
| otherwise = n : divise (n+1) a
What I want to happen is for it to keep moving up for values of n until one magically is evenly divisible by [1..20].
But this doesn't work and now I am stuck as from where to go from here. I assume I need to use:
[1..20]
for the value of a but I don't know how to implement this.
Well, having recently solved the Euler problem myself, I'm tempted to just post my answer for that, but for now I'll abstain. :)
Right now, the flow of your program is a bit chaotic, to sound like a feng-shui person. Basically, you're trying to do one thing: increment n until 1..20 divides n. But really, you should view it as two steps.
Currently, your code is saying: "if a doesn't divide n, increment n. If a does divide n, increment a". But that's not what you want it to say.
You want (I think) to say "increment n, and see if it divides [Edit: with ALL numbers 1..20]. If not, increment n again, and test again, etc." What you want to do, then, is have a sub-test: one that takes a number, and tests it against 1..20, and then returns a result.
Hope this helps! Have fun with the Euler problems!
Edit: I really, really should remember all the words.
Well, as an algorithm, this kinda sucks.
Sorry.
But you're getting misled by the list. I think what you're trying to do is iterate through all the available numbers, until you find one that everything in [1..20] divides. In your implementation above, if a doesn't divide n, you never go back and check b < a for n+1.
Any easy implementation of your algorithm would be:
lcmAll :: [Int] -> Maybe Int
lcmAll nums = find (\n -> all (divides n) nums) [1..]
(using Data.List.find and Data.List.all).
A better algorithm would be to find the lcm's pairwise, using foldl:
lcmAll :: [Int] -> Int
lcmAll = foldl lcmPair 1
lcmPair :: Int -> Int -> Int
lcmPair a b = lcmPair' a b
where lcmPair' a' b' | a' < b' = lcmPair' (a+a') b'
| a' > b' = lcmPair' a' (b + b')
| otherwise = a'
Of course, you could use the lcm function from the Prelude instead of lcmPair.
This works because the least common multiple of any set of numbers is the same as the least common multiple of [the least common multiple of two of those numbers] and [the rest of the numbers]
The function 'divise' never stops, it doesn't have a base case. Both branches calls divise, thus they are both recursive. Your also using the function divides as if it would return an int (like rem does), but it returns a Bool.
I see you have already started to divide the problem into parts, this is usually good for understanding and making it easier to read.
Another thing that can help is to write the types of the functions. If your function works but your not sure of its type, try :i myFunction in ghci. Here I've fixed the type error in divides (although other errors remains):
*Main> :i divise
divise :: Int -> Int -> [Int] -- Defined at divise.hs:4:0-5
Did you want it to return a list?
Leaving you to solve the problem, try to further divide the problem into parts. Here's a naive way to do it:
A function that checks if one number is evenly divisible by another. This is your divides function.
A function that checks if a number is dividable by all numbers [1..20].
A function that tries iterates all numbers and tries them on the function in #2.
Here's my quick, more Haskell-y approach, using your algorithm:
Prelude> let divisibleByUpTo i n = all (\x -> (i `rem` x) == 0) [1..n]
Prelude> take 1 $ filter (\x -> snd x == True) $ map (\x -> (x, divisibleByUpTo x 4)) [1..]
[(12,True)]
divisibleByUpTo returns a boolean if the number i is divisible by every integer up to and including n, similar to your divides function.
The next line probably looks pretty difficult to a Haskell newcomer, so I'll explain it bit-by-bit:
Starting from the right, we have map (\x -> (x, divisibleByUpTo x 4)) [1..] which says for every number x from 1 upwards, do divisibleByUpTo x 4 and return it in a tuple of (x, divisibleByUpTo x 4). I'm using a tuple so we know which number exactly divides.
Left of that, we have filter (\x -> snd x == True); meaning only return elements where the second item of the tuple is True.
And at the leftmost of the statement, we take 1 because otherwise we'd have an infinite list of results.
This will take quite a long time for a value of 20. Like others said, you need a better algorithm -- consider how for a value of 4, even though our "input" numbers were 1-2-3-4, ultimately the answer was only the product of 3*4. Think about why 1 and 2 were "dropped" from the equation.

What exactly does this Standard ML code do?

I'm reading Chris Okasaki's purely functional data structures, and there's one example I am having trouble with. It is located here. In particular, I don't understand how the rotate and exec functions work:
fun rotate($Nil, y::_, a) = $Cons (y, a)
| rotate ($Cons (x, xs), y :: ys, a) =
$Cons(x, rotate (xs, ys, $Cons (y, a)))
fun exec (f, r, $Cons (X, s)) = (f, r, s)
| exec (f, r, $Nil) = let val f' = rotate (f, r, $Nil) in (f', [], f') end
Could someone put this in stupid-people terms? I'm still learning my ML-based languages. :-)
That doesn't look like the Standard ML I learned (with $ characters in front of data constructors) but perhaps things have changed. Anyhow:
First of all there's a small typo on line 2 of rotate, you added a comma after $Cons
Basically rotate takes a tuple of three lists and assembles them in the order: first one ++ (reverse of second one) ++ third one. But it does this linearly by pulling elements from both list 1 and list 2 at the same time. The head of List 1 is cons'd to the final result (a o(1) operation). But the tail of list 2 is passed as an argument to the recursive call, and its head is cons'd onto the third argument, which amounts to reversing it.
That third argument is basically acting as an accumulator. In functional programming using an accumulator as an argument like that can be a trick for avoiding more expensive computations.
I admit to not understanding the purpose of exec. What's the context?
This doesn't explain the whole thing, but note that in fun rotate($Nil, y::_, a), the y::_ is a pattern that matches a list wherein you label the head of the list (first element) as y and the tail of the list (every item after the first element) as _. _ acts as a wildcard pattern.
Check out SML on Wikipedia, specifically the Mergesort implementation, for more use of :: patterns and _.

Resources