Prolog graph search - search

I have created a simple graph search from an example
move(math101, math102).
move(math101, chem101).
move(math102, math210).
move(math102, phys102).
move(phys102, phys201).
move(math210, phys201).
search(A, A, [A]).
search(A, B, [A|Path]) :-
move(A,C),
search(C,B,Path).
I can tell you that to get to 'phys201' from 'math101' you need to pass through 'math102' and 'math210' or 'math102' and'phys102'
I am trying to prove this in prolog but its not working, I think it may have something to do with the query i am typing
search(math101,phys201,[math101])
Or is it something in my code, I have traced the path and it keeps binning out with a No result
The trace is
[1]CALL: search(math101, phys201, [math101])
[1]FOUND: search(_4193470, _15353627, [_4193470|_14830180]):-move(_4193470, _8522358), search(_8522358, _15353627, _14830180).
[1]BIND: search(math101, phys201, [math101])
[2]CALL: move(math101, _10259988)
[2]FOUND: move(math101, math102).
[2]BIND: move(math101, math102)
[3]CALL: search(math102, phys201, [])
[3]FAIL: search(math102, phys201, [])
[2]REDO: move(math101, math102)
[4]CALL: move(math101, _10259988)
[4]FOUND: move(math101, chem101).
[4]BIND: move(math101, chem101)
[5]CALL: search(chem101, phys201, [])
[5]FAIL: search(chem101, phys201, [])
[4]REDO: move(math101, chem101)
[6]CALL: move(math101, _10259988)
[6]FAIL: move(math101, _10259988)
[1]REDO: search(math101, phys201, [math101])
Please help

as you suppose, your query is the problem: try
?- search(math101,phys201,X).
X = [math101, math102, math210, phys201] ;
X = [math101, math102, phys102, phys201] ;
false.
or, with some more instantiated path
?- search(math101,phys201,[math101|X]).
X = [math102, math210, phys201] ;
X = [math102, phys102, phys201] ;
false.

Related

Exception: Prelude.last: empty list in Haskell solving 8-queens?

I'm solving the 8-queens problem in Haskell using only basic functions nothing fancy
this is the code:
queens = [[x1,x2,x3,x4,x5,x6,x7,x8]|x1<-[1..8],x2<-[1..8],x3<-[1..8],x4<-[1..8],x5<-[1..8],x6<-[1..8],x7<-[1..8],x8<-[1..8],safeH [x2,x3,x4,x5,x6,x7,x8] x1,safeD [x2,x3,x4,x5,x6,x7,x8] x1 [x1,x2,x3,x4,x5,x6,x7,x8] 1]
safeH l e = if elem e l then False
else if length (l)/=0 then safeH(tail l)(head l)
else True
safeD l e xs n = if last(xs)/=e || length xs == 0 then
if length(l)/=0 then
if (head(l)+n==e || head(l)-n==e) then False
else safeD(tail l)(e)(xs)(n+1)
else safeD(tail xs)(head xs)(tail xs)(1)
else True
To clarify the SafeH function checks that no queens are in the same row H stands for Horizantly while the SafeD is supposed to check for diagonal conflicts
I am sure that the SafeH function is okay the problem with SafeD
and when compiling the code it gives me no problems but when calling the queens function
it gives me this error:
[1 of 1] Compiling Main ( y.hs, interpreted )
Ok, modules loaded: Main.
*Main> queens
*** Exception: Prelude.last: empty list
can anyone please help me?? thanks in advance for every thing :)
You can fix the immediate problem by checking the length of xs before calling last:
safeD l e xs n = if length xs == 0 || last(xs)/=e then ...
However, you will then run into another problem because you call safeD(tail xs)(head xs)(tail xs)(1) inside the then part of this branch, and you can reach the then part of this branch when length xs == 0.
I strongly recommend learning a little bit about pattern matching (Gentle Intro section, Haskell Report section) and trying to write this entire code snippet without ever calling head, tail, init, last, or length. Instead, use the two patterns [] for matching empty lists and (x:xs) (or similar) for matching lists that start as x and end with xs; if necessary, a call to reverse once in a while would be okay.
Good luck, and let us know how you fare and where you get stuck!
Ever thought of solving this problem for zero queens first?
Then for one queen?
Then spot the inductive / recursive pattern?.. I am not quoting the 3-liner solution, as it looks like your homework.

Error : parse error on input `='

I'm reading the Haskell book : http://learnyouahaskell.com/types-and-typeclasses
When I enter this line in the interpreter,
removeNonUppercase st = [c | c <- st, c `elem` ['A' .. 'Z']]
I get this error:
parse error on input `='
Whats causing this error ?
When defining variables or functions in the interpreter or in a GHCi script file (i.e. not a Haskell module), you need to use the let keyword.
> let removeNonUppercase st = [c | c <- st, c `elem` ['A' .. 'Z']]
This is because the interpreter essentially acts as if you were in a global do-block. Your code would be OK as-is in a Haskell source file.
If you got this error outside the interpreter, you probably either messed up the indentation, or you have some other syntax error in nearby code.

Haskell Stuck at parsing boolean logic

I'm currently writing a parser for a simple programming language. It's getting there however I'm unable to parse a boolean logic statement such as "i == 0 AND j == 0". All I get back is "non exhaustive patterns in case"
When I parse a boolean expression on its own it works fine e.g. "i == 0". Note "i == 0 a" will also return a boolean statement but "i == 0 AND" does not return anything.
Can anyone help please?
Whilst the above works correctly for input such as run parseBoolean "i == 0"
As #hammar points out, you should use Text.Parsec.Expr for this kind of thing. However, since this is homework, maybe you have to do it the hard way!
The problem is in parseArithmetic, you allow anyChar to be an operator, but then in the case statement, you only allow for +, -, *, /, %, and ^. When parseArithmetic tries to parse i == 0, it uses the first = as the operator, but can't parse an intExp2 from the second =, and fails in the monad, and backtracks, before getting to the case statement. However, when you try to parse i == 0 AND j == 0, it gets the i == part, but then it thinks that there's an arithmetic expression of 0 A ND, where A is an operator, and ND is the name of some variable, so it gets to the case, and boom.
Incidentally, instead of using the parser to match a string, and then using a case statement to match it a second time, you can have your parser return a function instead of a string, and then apply the function directly:
parseOp :: String -> a -> Parser a
parseOp op a = string op >> spaces >> return a
parseLogic :: Parser BoolExp
parseLogic = do
boolExp1 <- parseBoolExp
spaces
operator <- choice [ try $ parseOp "AND" And
, parseOp "OR" Or
, parseOp "XOR" XOr
]
boolExp2 <- parseBoolExp
return $ operator boolExp1 boolExp2
parseBoolean :: Parser BoolExp
parseBoolean = do
intExp1 <- parseIntExp
spaces
operator <- choice [ try $ parseOp "==" Main.EQ
, parseOp "=>" GTorEQ
, parseOp "<=" LTorEQ
]
intExp2 <- parseIntExp
return $ operator intExp1 intExp2

Converting seq<string> to string[] in F#

The example from this post has an example
open System.IO
let lines =
File.ReadAllLines("tclscript.do")
|> Seq.map (fun line ->
let newLine = line.Replace("{", "{{").Replace("}", "}}")
newLine )
File.WriteAllLines("tclscript.txt", lines)
that gives an error when compilation.
error FS0001: This expression was expected to have type
string []
but here has type
seq<string>
How to convert seq to string[] to remove this error message?
Building on Jaime's answer, since ReadAllLines() returns an array, just use Array.map instead of Seq.map
open System.IO
let lines =
File.ReadAllLines("tclscript.do")
|> Array.map (fun line ->
let newLine = line.Replace("{", "{{").Replace("}", "}}")
newLine )
File.WriteAllLines("tclscript.txt", lines)
You can use
File.WriteAllLines("tclscript.txt", Seq.toArray lines)
or alternatively just attach
|> Seq.toArray
after the Seq.map call.
(Also note that in .NET 4, there is an overload of WriteAllLines that does take a Seq)
Personally, I prefer sequence expressions over higher-order functions, unless you're piping the output through a series of functions. It's usually cleaner and more readable.
let lines = [| for line in File.ReadAllLines("tclscript.do") -> line.Replace("{", "{{").Replace("}", "}}") |]
File.WriteAllLines("tclscript.txt", lines)
With regex replacement
let lines =
let re = System.Text.RegularExpressions.Regex(#"#(\d+)")
[|for line in File.ReadAllLines("tclscript.do") ->
re.Replace(line.Replace("{", "{{").Replace("}", "}}"), "$1", 1)|]
File.WriteAllLines("tclscript.txt", lines)

Iterate over list in haskell?

I'm writing an audio program in Haskell using Portaudio. I have a function that generates a list of samples I'd like to play, and I'm trying to play them using the following snippet inside main:
curSamps <- return (chunk 1 (sineWave 440 44100))
forever $ do
Right numSampsAvail <- getStreamWriteAvailable paStream
Right NoError <- writeStream paStream curSamps numSampsAvail
curSamps <- return (drop numSampsAvail curSamps)
sineWave is a function I've created to generate an infinite list of Int16 samples of a sinewave at a specified frequency and sample rate.
When I debug this code, by replacing the audio output code with a putStrLn, it prints all 0s, which is the first sample from the function.
How can I iterate over this list with the audio output functions? I don't think I can use recursion or a map.
Edit: Code copying mistake
Use recursion:
play [] = return ()
play curSamps = do Right numSampsAvail <- getStreamWriteAvailable paStream
Right NoError <- writeStream paStream curSamps numSamps
play (drop numSampsAvail curSamps)
main = do ...
play (chunk 1 (sineWave 440 44100))
...
Consider using map's monadic cousins mapM/forM.
Using the same API functions one can do this:
let playSamples curSamps = do
Right numSampsAvail <- getStreamWriteAvailable paStream
Right NoError <- writeStream paStream curSamps numSampsAvail
playSamples (drop numSampsAvail curSamps)
playSamples (chunk 1 (sineWave 440 44100))
I'm not familiar with the Portaudio API, so it might provide a more convenient, higher-level way of doing what you're trying to achieve.

Resources