Haskell working with Math Logic - haskell

I'm working on this practice problem in which I have to write a bunch of functions in Haskell functional programming language. I manage to write some of them but not all, and I need those that I couldn't finish to proceed in the practice sheet. Can somebody suggest some ideas?
Here are the types I'm working with:
data Litteral = Pos Char | Neg Char
deriving (Show, Eq)
type Clause = [Litteral]
type Formule = [Clause]
type Distribution = [(Char, Bool)]
Here are the functions I was able to write:
negate :: Litteral -> Litteral
negate (Pos v) = Neg v
negate (Neg v) = Pos v
unitClaus :: Clause -> Bool
unitClaus [_] = True
unitClaus _ = False
associate :: Litteral -> (Char, Bool)
associate (Pos c) = (c, True)
associate (Neg c) = (c, False)
isTautology:: Clause -> Bool
isTautology [] = False
isTautology [_] = False
isTautology (x:xs)
| elem (negation x) xs = True
| otherwise = isTautology (xs)
I still need:
a function isEvidentContradictory that returns True if an expression (logical expression) contains at least two unit clauses, one of which contains a literal while the other contains the opposite literal; ex: [[a], [b], [- b]]
a function hasAlone if an expression contains a clause that contains only one literal ex: [[a], [a, b, - c]]
a function findAlone that checks if an expression verifies hasAlone and also returns the alone literal; ex: [[- a][b, c, e]] => [- a]
a function removeAlone that removes clause containing the alone literal from the expression

Using the functions you have already defined:
A function hasAlone if an expression contains a clause that contains only one literal ex: [[a], [a, b, - c]].
So basically, it checks item by item to see if it is an unit clause in which case it returns True.
hasAlone :: Formule -> Bool
hasAlone [] = False
hasAlone (x:xs)
| unitClaus x = True
| otherwise = hasAlone xs
A function findAlone that checks if an expression verifies hasAlone and also returns the alone literal; ex: [[- a][b, c, e]] => [- a].
In this case, I'm assuming you only want the literal for the first unit clause that shows up. It is the same idea that in hasAlone but instead of returning a Bool it returns the literal.
findAlone :: Formule -> Litteral
findAlone [] = error "No alone litteral"
findAlone (x:xs)
| unitClaus x = head x
| otherwise = findAlone xs
A function removeAlone that removes clause containing the alone literal from the expression.
In this case, I include two version, one that removes all the unit clauses and another that removes just the first one. See that if it isn't an unit clause I keep it by adding it at the top of the list that results from the recursion.
-- Removes all the unit clauses
removeAlone :: Formule -> Formule
removeAlone [] = []
removeAlone (x:xs)
| unitClaus x = removeAlone xs
| otherwise = x:(removeAlone xs)
-- Removes the first unit clauses
removeAlone1 :: Formule -> Formule
removeAlone1 [] = []
removeAlone1 (x:xs)
| unitClaus x = xs
| otherwise = x:(removeAlone xs)
A function isEvidentContradictory that returns True if an expression (logical expression) contains at least two unit clauses, one of which contains a literal while the other contains the opposite literal; ex: [[a], [b], [- b]].
In this case I started by assuming that expression means Formule (I hope that's okay). After that, the function checks item by item to see if it is a unit clause (same thing I have been doing in all the functions so far), in which case it looks for a unit clause containing the oposite literal in the rest of the list.
You could define an auxiliar function that does this part elem ((Main.negate (head x)):[]) xs, which is looking for the a unit clause containing the negative literal, just so that it looks neater.
isEvidentContradictory :: Formule -> Bool
isEvidentContradictory [] = False;
isEvidentContradictory (x:xs)
| unitClaus x = elem ((Main.negate (head x)):[]) xs || isEvidentContradictory xs
| otherwise = isEvidentContradictory xs

Related

Defining my own isPrefixOf without recursion using foldr

I am working on a programming assignment where I must define my own version of isPrefixOf from Data.List using only foldr, map, and cons (and thus no recursion). The hint I've been given is that the return value of foldr should itself be a function. Can someone help me understand how I could apply that fact? My guess for the structure is included below.
startsWith :: String -> String -> Bool
startsWith s1 s2 = (foldr (???) ??? s1) s2
I am allowed to define my own helper functions. For the curious this is from an assignment for CIS 552 at Penn.
EDIT: It turns out that by folding over the pattern instead of the string, the code gets a lot simpler and shorter and something like
"" `isPrefixOf` undefined
works. Thank you #dfeuer and #WillNess. This is the updated program:
isPrefixOf pattern s = foldr g (const True) pattern s
where
g x r (h:t)
| x == h = r t
| otherwise = False
It works almost the same way as the below program, so refer to that for the explanation.
I managed to solve it using nothing but foldr:
isPrefixOf :: String -> String -> Bool
p `isPrefixOf` s = isPrefixOfS p
where
isPrefixOfS
= foldr
(\c acc ->
\str -> case str of
x:xs -> if c == x
then acc xs
else False
[] -> True
)
null
s
Here's the explanation.
In order to create the function isPrefixOf, we want this:
isPrefixOf pattern s
= case pattern of
[] -> True
x:xs -> if (null s) then False
else if (head s) /= x
then False
else xs `isPrefixOf` (tail s)
Well, let's simplify this - let's create a function called isPrefixOfS that only takes a pattern, which it compares to s automatically. We need to build this chain of nested functions:
-- Pseudocode, not actual Haskell
\p -> case p of
[] -> True
x:xs -> if x /= (s !! 0)
then False
else <apply xs to> \q -> case q of [] -> True
x:xs -> if x /= (s !! 1) -- Note that we've incremented the index
then False
else <apply xs to> \r -> ....
This seems pretty self explanatory - let me know in a comment if it requires further explanation.
Well, we can see that this chain has a recursive property to it, where the last character of s will be compared in the most deeply nested lambda. So we need to nest lambdas from right to left. What can we use for that? foldr.
isPrefixOfS
= foldr -- Folding from right to left across `s`
(\c acc -> -- `c` is the current character of `s`, acc is the chain of nested functions so far
\str -> -- We return a function in the fold that takes a String
case str of
-- If the string is not null:
x:xs -> if c == x -- If the head of the string is equal to the current character of s,
then acc xs -- Then pass the tail of the string to the nested function which will compare it with subsequent characters of s
else False -- Otherwise we return false
-- If the string is null, we have completely matched the prefix and so return True
[] -> True
)
null -- Innermost nested function - we need to make sure that if the prefix reaches here, it is null, i.e. we have entirely matched it
s
And now we use this function isPrefixOfS on p:
p `isPrefixOf` s = isPrefixOfS p
EDIT: I just found this post which uses a similar logic to implement zip in terms of foldr, you may want to look at that as well.

Find index of substring in another string Haskell

I am to make a function which takes two parameters (Strings). The function shall see if the first parameter is a substring of the second parameter. If that is the case, it shall return tuples of each occurences which consists of the startindex of the substring, and the index of the end of the substring.
For example:
f :: String -> String -> [(Int,Int)]
f "oo" "foobar" = [(1,2)]
f "oo" "fooboor" = [(1,2),(4,5)]
f "ooo" "fooobar" = [(1,3)]
We are not allowed to import anything, but I have a isPrefix function. It checks if the first parameter is a prefix to the second parameter.
isPrefix :: Eq a => [a] -> [a] -> Bool
isPrefix [] _ = True
isPrefix _ [] = False
isPrefix (x:xs) (y:ys) |x== y = isPrefix xs ys
|otherwise = False
I was thinking a solution may be to run the function "isPrefix" first on x, and if it returns False, I run it on the tail (xs) and so on. However, I am struggling to implement it and struggling to understand how to return the index of the string if it exists. Perhaps using "!!"? Do you think I am onto something? As I am new to Haskell the syntax is a bit of a struggle :)
We can make a function that will check if the first list is a prefix of the second list. If that is the case, we prepend (0, length firstlist - 1) to the recursive call where we increment both indexes by one.
Ths thus means that such function looks like:
f :: Eq a => [a] -> [a] -> [(Int, Int)]
f needle = go
where go [] = []
go haystack#(_: xs)
| isPrefix needle haystack = (…, …) : tl -- (1)
| otherwise = tl
where tl = … (go xs) -- (2)
n = length needle
Here (1) thus prepends (…, …) to the list; and for (2) tl makes a recursive call and needs to post-process the list by incrementing both items of the 2-tuple by one.
There is a more efficient algorithm to do this where you pass the current index in the recursive call, or you can implement the Knuth-Morris-Pratt algorithm [wiki], I leave these as an exercise.

Function rem1 :: Eq a => [a] -> a -> [a], that removes the elem mentioned in the second argument from the first argument

I need to make a function that removes the first occurrence of an element, given in the second argument, from the list given as the first argument.
The print should for example look like this:
rem1 "abab" 'a' == "bab"
rem1 "abab" 'b' == "aab"
rem1 "abab" 'c' == "abab"
Completely new to Haskell and not sure where to begin. Any helpers? :)
Edit:
This is what I have now, and it gives me "variable not in scope"
rem1 :: Eq a => [a] -> a -> [a]
rem1 [] _ = []
rem1 (x:xs) y
| x == y = xs
| otherwise = x : rem1 xs y
You can use explicit recursion here. There are basically three cases here:
the list is empty, in which case we did not find an element, then we can return the empty list;
the list is not empty, and the first element matches the element we search for, in that case we return the rest of the elements; and
the list is not empty and the first element does not match the element we are looking for. In that case we yield the first element, and we recurse on the rest of the list.
The "skeleton" of the function thus looks like:
rem1 :: Eq a => [a] -> a -> [a]
rem1 [] _ = … -- (1)
rem1 (x:xs) y
| x == y = … -- (2)
| otherwise = … -- (3)
where you still need to fill in the … parts based on the corresponding description.

Pattern Match Fail when `function [] _ = ...; function _ [] = ...` syntax is omitted

Though disjoint exhausts all possible patterns in its guard conditions, Haskell gives me a PatternMatchFail error when running it.
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint l#(x:xs) r#(y:ys)
| null l || null r = True
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
-- | Terminates when either list has been reduced to null, or when their head
-- elements are equal. Since lists are ordered, it only needs to compare head elements.
However, it has no problem if I write:
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint [] _ = True
disjoint _ [] = True
disjoint l#(x:xs) r#(y:ys)
-- | null l || null r = True -- now redundant, but included for sake of continuity
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
Without those additional lines, I get a PatternMatchFail. If I am to infer what the issue for Haskell is in the first case, it is that if given a null list for an input argument, its expected arguments l#(x:xs) r#(y:ys) are already invoking a pattern-match, one that is non-exhaustive in the case of a null list, resulting in a PatternMatchFail, despite having a guard condition that checks for exactly the same condition. It just can't ever reach the guard condition, because it first needs to match on the "argument condition".
However, those additional two lines are a tad off-putting to me in their repetitiveness, and I was just wondering if there was a more succinct way of fixing this. More generally: if I were to be using three or more lists as arguments, I definitely wouldn't want to write out disjoint 3+ more times just to check for null conditions, so what might I do in cases like that? Thank you for your time.
Your explaination for why this gives a pattern match failure is correct. You can write the code the following way to avoid redundant lines:
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint l#(x:xs) r#(y:ys)
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
disjoint _ _ = True -- catch all pattern, executed if either l or r is []
This is the solution I recommend. There is another solution, to make the pattern match more lazy (the pattern is then only checked if x/xs or y/ys is actually required):
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint l# ~(x:xs) r# ~(y:ys) -- the ~ here says that this is an irrefutable pattern, which makes the match more lazy
| null l || null r = True -- x/y is not required, so pattern not checked
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
I don't recommend doing this though, since checking for null explicitly does not feel like idiomatic Haskell (also, irrefutable patterns are rarely used). The problem with the second approach is that you have to take care that you don't access y/ys / x/xs in the null cases, and the compiler won't help you. The first approach guarrantes that you can't access them in the null cases.
Another way to avoid the duplication is to take advantage of pattern match/guard fall through:
disjoint :: (Ord a) => [a] -> [a] -> Bool
disjoint l r
| null l || null r = True
-- If the guard above fails, then this pattern match is attempted:
disjoint l#(x:xs) r#(y:ys)
| x == y = False
| x > y = disjoint l ys -- reduce right list
| otherwise = disjoint xs r -- reduce left list
This is overkill here and personally I prefer the explicit pattern matching over null (the style of the first code block in bennofs answer is what I would go for), but this general technique can be handy in some situations.

Breaking down a haskell function

I'm reading Real world haskell book again and it's making more sense. I've come accross this function and wanted to know if my interpretation of what it's doing is correct. The function is
oddList :: [Int] -> [Int]
oddList (x:xs) | odd x = x : oddList xs
| otherwise = oddList xs
oddList _ = []
I've read that as
Define the function oddList which accepts a list of ints and returns a list of ints.
Pattern matching: when the parameter is a list.
Take the first item, binding it to x, leaving the remainder elements in xs.
If x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. Repeat...
When x isn't odd, just return the result of applying oddList to xs
In all other cases return an empty list.
1) Is that a suitable/correct way of reading that?
2) Even though I think I understand it, I'm not convinced I've got the (x:xs) bit down. How should that be read, what's it actually doing?
3) Is the |...| otherwise syntax similar/same as the case expr of syntax
1 I'd make only 2 changes to your description:
when the parameter is a nonempty list.
f x is an odd number prepend x to the result of applying oddList to the remaining elements xs and return that result. [delete "Repeat...""]
Note that for the "_", "In all other cases" actually means "When the argument is an empty list", since that is the only other case.
2 The (x:xs) is a pattern that introduces two variables. The pattern matches non empty lists and binds the x variable to the first item (head) of the list and binds xs to the remainder (tail) of the list.
3 Yes. An equivalent way to write the same function is
oddList :: [Int] -> [Int]
oddList ys = case ys of { (x:xs) | odd x -> x : oddList xs ;
(x:xs) | otherwise -> oddList xs ;
_ -> [] }
Note that otherwise is just the same as True, so | otherwise could be omitted here.
You got it right.
The (x:xs) parts says: If the list contains at least one element, bind the first element to x, and the rest of the list to xs
The code could also be written as
oddList :: [Int] -> [Int]
oddList (x:xs) = case (odd x) of
True -> x : oddList xs
False -> oddList xs
oddList _ = []
In this specific case, the guard (|) is just a prettier way to write that down. Note that otherwise is just a synonym for True , which usually makes the code easier to read.
What #DanielWagner is pointing out, is we in some cases, the use of guards allow for some more complex behavior.
Consider this function (which is only relevant for illustrating the principle)
funnyList :: [Int] -> [Int]
funnyList (x1:x2:xs)
| even x1 && even x2 = x1 : funnyList xs
| odd x1 && odd x2 = x2 : funnyList xs
funnyList (x:xs)
| odd x = x : funnyList xs
funnyList _ = []
This function will go though these clauses until one of them is true:
If there are at least two elements (x1 and x2) and they are both even, then the result is:
adding the first element (x1) to the result of processing the rest of the list (not including x1 or x2)
If there are at least one element in the list (x), and it is odd, then the result is:
adding the first element (x) to the result of processing the rest of the list (not including x)
No matter what the list looks like, the result is:
an empty list []
thus funnyList [1,3,4,5] == [1,3] and funnyList [1,2,4,5,6] == [1,2,5]
You should also checkout the free online book Learn You a Haskell for Great Good
You've correctly understood what it does on the low level.
However, with some experience you should be able to interpret it in the "big picture" right away: when you have two cases (x:xs) and _, and xs only turns up again as an argument to the function again, it means this is a list consumer. In fact, such a function is always equivalent to a foldr. Your function has the form
oddList' (x:xs) = g x $ oddList' xs
oddList' [] = q
with
g :: Int -> [Int] -> [Int]
g x qs | odd x = x : qs
| otherwise = qs
q = [] :: [Int]
The definition can thus be compacted to oddList' = foldr g q.
While you may right now not be more comfortable with a fold than with explicit recursion, it's actually much simpler to read once you've seen it a few times.
Actually of course, the example can be done even simpler: oddList'' = filter odd.
Read (x:xs) as: a list that was constructed with an expression of the form (x:xs)
And then, make sure you understand that every non-empty list must have been constructed with the (:) constructor.
This is apparent when you consider that the list type has just 2 constructors: [] construct the empty list, while (a:xs) constructs the list whose head is a and whose tail is xs.
You need also to mentally de-sugar expressions like
[a,b,c] = a : b : c : []
and
"foo" = 'f' : 'o' : 'o' : []
This syntactic sugar is the only difference between lists and other types like Maybe, Either or your own types. For example, when you write
foo (Just x) = ....
foo Nothing = .....
we are also considering the two base cases for Maybe:
it has been constructed with Just
it has been constructed with Nothing

Resources