2 Haskell Questions - haskell

I have 2 Question about 2 haskell functions
flipSymbol :: Model -> Atom -> Model This function must take a Model and an Atom and flip the truth value of the atom in the model. Now I was thinking of writing this function like this:...
flipSymbol m a = map f m
where
f (atom, value) = if a == atom then (atom, not value) else (atom, value)
Is there a better way?
The second one is a something more complicated and I need some help with it if possible..
In order to check the satisfiability of a formula in a given model we propagate the effects of assigning a truth value to an atom in a formula. Assume an atom to which we assign the value True. The following effects
can be applied to the formula:
The positive literals have the same True value and, therefore, any clauses that contain them are removed from the formula. This is to indicate that these clauses could be satisfied and hence no longer affect the satisfiability of the formula.
The negated literals have a value of False and are, therefore, removed from any clause they are in. This is to indicate that these clauses are still not satisfied and can only be made true by one of the other literals obtaining a value of True. In the case where False is assigned to the atom, the positive literals will now be false and should be removed
from their clauses while the negative literals will become true and have their clauses removed from the formula.
For example, in the formula (P _ Q _ R) ^ (:P _ Q _ :R) ^ (P _ :Q), assume we assign True to P. Then the clauses containing P, ie. (P _ Q _ R) and (P _ :Q) are removed from the formula, whereas :P is removed from any clause it is in, ie. (:P _ Q _ :R). This results in the formula (Q _ :R). On the other hand, if we assign False to P, we then remove (:P _ Q _ :R) from the formula and P from its clauses, thus obtaining (Q _ R) ^ (:Q).
The overall formula is satisfiable if it can be reduced to the empty list since in this case all the clauses were satisfied. If there is an empty list within the overall formula then that means that a clause was not satisfied and hence the formula can not be satisfied with the assignment that led to this state.
assign :: (Atom,Bool) -> Formula -> Formula The assign function should take an (Atom,Bool) pair and a formula and propagate the effects of assigning the given truth value to the atom in the formula as described above.
The code(on which I received help from here also):
module Algorithm where
import System.Random
import Data.Maybe
import Data.List
type Atom = String
type Literal = (Bool,Atom)
type Clause = [Literal]
type Formula = [Clause]
type Model = [(Atom, Bool)]
type Node = (Formula, ([Atom], Model))
-- This function takess a Clause and return the set of Atoms of that Clause.
atomsClause :: Clause -> [Atom]
atomsClause = undefined
-- This function takes a Formula returns the set of Atoms of a Formula
atoms :: Formula -> [Atom]
atoms = nub . map snd
-- This function returns True if the given Literal can be found within
-- the Clause.
isLiteral :: Literal -> Clause -> Bool
isLiteral = isLiteral = any . (==)
-- this function takes a Model and an Atom and flip the truthvalue of
-- the atom in the model
flipSymbol :: Model -> Atom -> Model -- is this ok?
flipSymbol m a = map f m where
f (atom, value) = if a == atom
then (atom, not value)
else (atom, value)
assign :: (Atom,Bool) -> Formula -> Formula
assign = undefined --any advice here?

At a glance, I can't see any way to improve your first formula, maybe you may use logical functions instead of a if-then-else, it's faster:
flipSymbol m a = map f m where
f (atom, value) = (atom, value /= (a == atom))
Notice: /= for Bool is basically xor.
To your last question:
The basic idea is to compare the Atoms, incorporate the Bool-values and fiddeling around with logical ops to get your result. Basically, it looks like this:
assign :: (Atom,Bool) -> Formula -> Formula
assign (a,b) = map . (map f) where
f (x,b) = (x,(x==a)&&b)

Related

Understanding Haskell laziness in case of "if then else"

Currently I'm trying to learn Haskell by following a FP in Haskell course from University of Pennsylvania.
In one of the assignments, I had to define the following type classes to implement expression evaluating calculator :
class Expr a where
mul :: a -> a -> a
add :: a -> a -> a
lit :: Integer -> a
class HasVars a where
var :: String -> a
And a data type which mimics a math expression which can contain, addition, multiplication of integers and also can hold a variable in the expression.
data VarExprT = VarLit Integer
| VarAdd VarExprT VarExprT
| VarMul VarExprT VarExprT
| Var String
deriving (Show, Eq)
instance HasVars VarExprT where
var = Var
instance Expr VarExprT where
lit = VarLit
add = VarAdd
mul = VarMul
Now to simulate the operations of adding, multiplying in an expression with variables, I had to create instances of above typeclasses as below :
instance HasVars (M.Map String Integer -> Maybe Integer) where
var str = \mMap -> M.lookup str mMap
instance Expr (M.Map String Integer -> Maybe Integer) where
lit x = \mMap -> Just x
add f1 f2 = \mMap -> if isNothing (f1 mMap) || isNothing (f2 mMap)
then
Nothing
else
Just (fromJust (f1 mMap) + fromJust (f2 mMap))
mul f1 f2 = \mMap -> if isNothing (f1 mMap) || isNothing (f2 mMap)
then
Nothing
else
Just (fromJust (f1 mMap) * fromJust (f2 mMap))
And to actually evaluate expressions the below function was provided :
withVars :: [(String, Integer)] -> (M.Map String Integer -> Maybe Integer)-> Maybe Integer
withVars vs exp = exp $ M.fromList vs
So using above function in ghci looks like below :
*Calc> withVars [("x", 6)] $ add (lit 3) (mul (lit 6) (var "x"))
Just 39
*Calc> withVars [("x", 6)] $ add (lit 3) (var "y")
Nothing
So my query is the following :
In a normal expression in Haskell, expressions are evaluated only when they are needed which is still not very intuitive to me, but I sort of get it.
But in first expression above, how will it the internal evaluation work for the expression in the condition ?
Because as I understand, first add is taking place so the if condition will be checked.
And the condition will have to get evaluated to a point where it comes to True or evaluate fully to False. But in the second expression of the || it is going to try to evaluate the mul expression (mul (lit 6) (var "x")) mMap corresponding to f2 mMap.
And now again there is an if condition in mul. So I'm confused as to how exactly will the evaluations play out because of the recurring if conditions coming in the middle of expression evaluations.
PS : The M.Map and so on is because of import qualified Data.Map as M
The definition of || is lazy, and will evaluate the second argument only when needed, i.e. when the first argument is false.
You can test it in GHCi, observing that the following does not trigger the error.
> True || error "ouch!"
True
In your case, isNothing (f1 mMap) || isNothing (f2 mMap) will first evaluate isNothing (f1 mMap) and if that is true it will skip the evaluation of isNothing (f2 mMap).
Note that this is essentially the same "short-circuiting" semantics of the boolean operator || which is commonly found in C, C++, Java, and many other languages. There, evaluating f() || g() won't call g unless f() evaluates to false.
Minor digression on the style
You shouldn't use fromJust -- that's a partial function that can crash the program if you forget to check for Nothing. In your code you do check against that, but that's not the recommended style.
You code suffers from "boolean blindness": you have two Maybe Integer values, and instead of testing them directly, you first transform them into boolean, losing precious information (the integer inside). Since you lost that information in the test, you then need to resort to dangerous tools like fromJust to recover the information you lost in the test.
The common practice here is to avoid booleans, avoid if, and use pattern matching to test the Maybe Integer values directly.
add f1 f2 = \mMap -> case (f1 mMap, f2 mMap) of
(Nothing, _ ) -> Nothing
(_ , Nothing) -> Nothing
(Just i1, Just i2) -> Just (i1 + i2)
(There are library functions to shorten that, but it's irrelevant).
The code above uses no booleans at all. It also will evaluate f2 mMap only when needed, i.e. only if the (_ , Nothing) -> Nothing line is reached, i.e. only when f1 mMap was not a Nothing. This provides the same lazy semantics as the previous code using booleans and ||.

Haskell Pattern Matching Booleans

I need help to fix this Haskell function using pattern matching. It should only return true if every formula in the list of formulas is True. Here is what I have so far:
eval_list :: [Formula] -> Bool
eval_list (f:fx) = (eval_list f) && (eval_list fx)
here is how Formula is defined:
data Formula = And Formula Formula
| Not Formula
| Con Bool
deriving Show
You forgot to implement the case for an empty list. Since you each time recurse with a list item that is one item shorter than the previous call, eventually you will make a recursive call with an empty list.
Another problem is that you call eval_list f, but f is the first item of your list and thus a Formula object, not a list of Formulas. You likely should use a eval_formula to evaluate the formula.
You thus can implement this with:
eval_list :: [Formula] -> Bool
eval_list [] = True
eval_list (f:fx) = eval_formula f && eval_list fx
where you will have to implement eval_formula yourself.
You do not need to use explicit recursion. You can for example work with all :: Foldable f => (a -> Bool) -> f a -> Bool:
eval_list :: Foldable f => f Formula -> Bool
eval_list = all eval_formula
In order to evaluate a single Formula, you can use recursion, the function thus will look like:
eval_formula :: Formula -> Bool
eval_formula (And f1 f2) = …
eval_formula (Not f) = …
eval_formula (Con b) = …
where I leave implement the … parts as an exercise.

Changing the return type of a function in Haskell?

Is there is a succinct way to change the return type of a function?
Consider for example comparing in Data.Ord. It returns an Ordering. Yet I am only interested in whether the two items are equal or not. So I need to convert the resulting Ordering to a Bool.
A straight forward way I can think of is:
isEqualOn f x y = if comparing f x y==EQ then True else False
(or isEqualOn f x y = comparing f x y==EQ as here as pointed out in the comments).
Is there a more compositional way to do this (sort of adapting comparing or writing it in a pointless manner) without having to write out everything? Ideally, I am looking for something that works on n-ary functions as well.
-- Update --
As suggested by the answers/comments, the specific example above (isEqualOn) can be implemented using the standard on function as on (==). However, my question is about the general technique to change function return types in a compositional/pointless manner as exemplified by the SEC approach in the comments.
Your definition of isEqualOn would be the same as on (==):
\> import Data.Function (on)
\> :t (on (==))
(on (==)) :: Eq a1 => (a -> a1) -> a -> a -> Bool
for example to compare on absolute value:
\> let isEqualOn = on (==)
\> isEqualOn abs 2 (-2)
True
As mentioned you can use the function on from Data.Function, but
perhaps you are looking for the operator == which returns a Bool.
In which case your function can be written as:
isEqualOn f x y = fx == fy
and personally I would never write this particular function but
"inline" it where it is used.
On the more general matter of "changing the return type". What you are looking for is composition:
isEq Eq = True
isEq _ = False
equal x y = isEq (comparing x y)
or more haskell flavored:
equal x = isEq . comparing x

How to break up complex type aliases in haskell?

I came across this very old sudoku code which seems greek to me coz of mainly this ugly type
type T = (Int,Int) -> [Int]
To understand this function for instance
mark :: ((Int,Int),Int) -> T -> T
mark (p#(i,j),n) s q#(x,y) =
if p==q then [n] else
if x==i || y==j || e x i && e y j then delete n $ s q else s q
where e a b = div (a-1) 3==div (b-1) 3
I can replace the T with the actual type
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
mark (p#(i,j),n) s q#(x,y) =
Now the type arguments don't seem to line up properly. p matches perfectly, but i get confused with "s". If I jump into the call for mark it's like this.....here the list I can easily see it's array of key value pairs with keys like (1,2) etc. These have been filtered for blanks or zeros in sudoku.
input :: String -> (Int,Int) -> [Int]
input s = foldr mark (const [1..9]) $
[(p,n) | (p,n) <- zip idx $ map read $ lines s >>= words, n>0]
The mark function is called with this list and accumulator which is a function (const [1..9]). This doesn't fit the type signature.
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
Problem with the code is that I can't see the actual result of the mark function which I still don't understand. When it's passed to a third function it gets some output. Any explanation on how to understand this sphagetti code?
A value of this type
type T = (Int,Int) -> [Int]
maps the coordinates of any sudoku cell (x,y) :: (Int,Int) into a set of the possible values such cell might have (represented as a list of digits [Int]).
The function const [0..9] maps any cell into the set of all digits. It acts as the initial state for a sudoku solver: at the beginning, assume any cell may have any digit.

Notation for a recursive call on user defined type [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Iterating through a String and replacing single chars with substrings in haskell
I'm trying to implement a function that looks at a String ([Chars]) and checks for every letter whether this letter should be replaced with another string. For example we might have a [Chars] consisting of "XYF" and rules that says "X = HYHY", "Y = OO", then our output should become "HYHYOOF".
I want to use the following two types which I have defined:
type Letters = [Char]
data Rule = Rule Char Letters deriving Show
My idea is that the function should look something like the following below using guards. The problem is however I can't find any information on how to the recursive call should look like when i want browse through all my rules to see if any of them fits to the current letter x. I hope anyone can give some hints on how the notation goes.
apply :: Letters -> [Rule] -> Letters
apply _ _ = []
apply (x:xs) (Rule t r:rs)
| x /= t = apply x (Rule t rs)
| x == t = r++rs:x
| otherwise =
I would suggest a helper function to check whether a rule matches,
matches :: Char -> Rule -> Bool
matches c (Rule x _) = c == x
and then you check for each character whether there are any matching rules
apply :: Letters -> [Rule] -> Letters
apply [] _ = []
apply s [] = s
apply (c:cs) rules = case filter (matches c) rules of
[] -> c : apply cs rules
(Rule _ rs : _) -> rs ++ apply cs rules
If you try an explicit recursion on rules within apply, it will become too ugly, since you need to remember the full rules list for replacing later characters.
I'd suggest that you learn to do this with generic utility functions. Two key functions that you want here:
lookup :: Eq a => a -> [(a, b)] -> Maybe b. Finds a mapping in an association list—a list of pairs used to represent a map or dictionary.
concatMap :: (a -> [b]) -> [a] -> [b]. This is similar to map, but the function mapped over the list returns a list, and the results are concatenated (concatMap = concat . map).
To use lookup you need to change your Rule type to this more generic synonym:
type Rule = (Char, String)
Remember also that String is a synonym for [Char]. This means that concatMap, when applied to String, replaces each character with a string. Now your example can be written this way (I've changed argument orders):
apply :: [Rule] -> String -> String
apply rules = concatMap (applyChar rules)
-- | Apply the first matching rule to the character.
applyChar :: [Rule] -> Char -> String
applyChar rules c = case lookup c rules of
Nothing -> [c]
Just str -> str
-- EXAMPLE
rules = [ ('X', "HYHY")
, ('Y', "OO") ]
example = apply rules "XYF" -- evaluates to "HYHYOOF"
I changed the argument order of apply because when an argument has the same type as the result, it often helps to make that argument the last one (makes it easier to chain functions).
We can go further and turn this into a one-liner by using the utility function fromMaybe :: a -> Maybe a -> a from the Data.Maybe module (fromMaybe default Nothing = default, fromMaybe default (Just x) = x):
import Data.Maybe
apply rules = concatMap (\c -> fromMaybe [c] $ lookup c rules)
An exercise you can do to complement this is to write your version of all of these utility functions on your own by hand: lookup, concatMap (break it down into concat :: [[a]] -> [a] and map :: (a -> b) -> [a] -> [b]), and fromMaybe. That way you can understand the "full stack" involved in this solution.
My solution is structurally similar to the other ones, but uses monads:
import Control.Monad
import Data.Functor
import Data.Maybe
match :: Char -> Rule -> Maybe Letters
match c (Rule c' cs) = cs <$ guard (c == c')
apply :: Letters -> [Rule] -> Letters
apply cs rules =
[s | c <- cs
, s <- fromMaybe [c] $ msum $ map (match c) rules]
The first monad we're dealing with is Maybe a. It is actually a little bit more, a MonadPlus, which allows us to use msum (which boils down something like [Nothing, Just 2, Nothing, Just 3] to the first "hit", here Just 2).
The second monad is [a], which allows us to use a list comprehension in apply.

Resources