In my program for solving discrete maths, I want to let the user input a string of logic operations; e.g., if the user inputs let f (x:y:_) = x && y, then I would get a function f for use in the rest of the program. In GHCi, I can easily test my program by inputting let f (x:y:_) = x && y.
I have no idea how to achieve this task. I have taken a look into the eval function from the plugins package, but it seems not to be the right function. Can I do this in Haskell?
The code I'm planning to use this with is:
type TruthTable = [[Bool]]
type TruthTableResult = [([Bool], Bool)]
solveTable :: ([Bool] -> Bool) -> Integer -> (TruthTableResult)
solveTable f n = let table = truthTable n
result = map f table
in zipWith (\v r -> (v, r)) table result
There is no standard Haskell function, because Haskell is complied, not interpreted. However, there are libraries that allow you to read and compile Haskell code at run time. One of them is hint. Example for your case:
import Control.Monad
import Language.Haskell.Interpreter
main = do
-- fExpr is a Haskell code supplied by your user as a String
let fExpr = "let f (x:y:_) = x && y in f"
-- Create an interpreter that runs fExpr
r <- runInterpreter $ do
setImports ["Prelude"]
interpret fExpr (const True :: [Bool] -> Bool)
-- run it and get an interface to the function
case r of
Left err -> putStrLn $ "Ups... " ++ (show err)
Right f -> do
print $ f [True, False]
print $ f [True, True]
More examples available here.
You are writing an eval function - a form of runtime metaprogramming.
eval :: String -> a
If the string represents a Haskell program, then you must parse the string, type check it, and then compile it to a target interpreter or runtime. This requires access to the compiler as a library, either exported as a runtime service (in an interpreter) or as a separate package (as for a compiler).
The GHC implementation of Haskell has several libraries for doing runtime evaluation of Haskell code:
via the GHCi interpreter- hint
via the compiler - plugins
These apply only if your input language is Haskell.
If instead your input string represents a program in some other language, then you are looking for a DSL interpreter. This can be done by writing your own interpreter for the input language (or reusing a library if it is a common language).
The short answer is that Haskell has no "eval" function, unlike interpreted languages which can do this quite easily (after all, they have the interpreter handy and already running).
You can include the Haskell compiler as a library: see http://www.haskell.org/haskellwiki/GHC/As_a_library. This is the nearest thing to what you ask for.
However it sounds like you don't want the whole of Haskell here; what you are really want is a different language which may have Haskell-like syntax but is not the whole of Haskell. If so then the real solution is to define that language and write a parser for it. The Parsec library is the place to start for that.
Related
Graham Hutton, in the 2nd edition of Programming in Haskell, spends the last 2 chapters on the topic of stack machine based implementation of an AST.
And he finishes by showing how to derive the correct implementation of that machine from the semantic model of the AST.
I'm trying to enlist the help of Data.SBV in that derivation, and failing.
And I'm hoping that someone can help me understand whether I'm:
Asking for something that Data.SBV can't do, or
Asking Data.SBV for something it can do, but asking incorrectly.
-- test/sbv-stack.lhs - Data.SBV assisted stack machine implementation derivation.
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.SBV
import qualified Data.SBV.List as L
import Data.SBV.List ((.:), (.++)) -- Since they don't collide w/ any existing list functions.
-- AST Definition
data Exp = Val SWord8
| Sum Exp Exp
-- Our "Meaning" Function
eval :: Exp -> SWord8
eval (Val x) = x
eval (Sum x y) = eval x + eval y
type Stack = SList Word8
-- Our "Operational" Definition.
--
-- This function attempts to implement the *specification* provided by our
-- "meaning" function, above, in a way that is more conducive to
-- implementation in our available (and, perhaps, quite primitive)
-- computational machinery.
--
-- Note that we've (temporarily) assumed that this machinery will consist
-- of some form of *stack-based computation engine* (because we're
-- following Hutton's example).
--
-- Note that we give the *specification* of the function in the first
-- (commented out) line of the definition. The derivation of the actual
-- correct definition from this specification is detailed in Ch. 17 of
-- Hutton's book.
eval' :: Exp -> Stack -> Stack
-- eval' e s = eval e : s -- our "specification"
eval' (Val n) s = push n s -- We're defining this one manually.
where
push :: SWord8 -> Stack -> Stack
push n s = n .: s
eval' (Sum x y) s = add (eval' y (eval' x s))
where
add :: Stack -> Stack
add = uninterpret "add" s -- This is the function we're asking to be derived.
-- Now, let's just ask SBV to "solve" our specification of `eval'`:
spec :: Goal
spec = do x :: SWord8 <- forall "x"
y :: SWord8 <- forall "y"
-- Our spec., from above, specialized to the `Sum` case:
constrain $ eval' (Sum (Val x) (Val y)) L.nil .== eval (Sum (Val x) (Val y)) .: L.nil
We get:
λ> :l test/sbv-stack.lhs
[1 of 1] Compiling Main ( test/sbv-stack.lhs, interpreted )
Ok, one module loaded.
Collecting type info for 1 module(s) ...
λ> sat spec
Unknown.
Reason: smt tactic failed to show goal to be sat/unsat (incomplete quantifiers)
What happened?!
Well, maybe, asking SBV to solve for anything other than a predicate (i.e. - a -> Bool) doesn't work?
The fundamental issue here is that you are mixing SMTLib's sequence logic and quantifiers. And the problem turns out to be too difficult for an SMT solver to handle. This sort of synthesis of functions is indeed possible if you restrict yourself to basic logics. (Bitvectors, Integers, Reals.) But adding sequences to the mix puts it into the undecidable fragment.
This doesn't mean z3 cannot synthesize your add function. Perhaps a future version might be able to handle it. But at this point you're at the mercy of heuristics. To see why, note that you're asking the solver to synthesize the following definition:
add :: Stack -> Stack
add s = v .: s''
where (a, s') = L.uncons s
(b, s'') = L.uncons s'
v = a + b
while this looks rather innocent and simple, it requires capabilities beyond the current abilities of z3. In general, z3 can currently synthesize functions that only make a finite number of choices on concrete elements. But it is unable to do so if the output depends on input for every choice of input. (Think of it as a case-analysis producing engine: It can conjure up a function that maps certain inputs to others, but cannot figure out if something should be incremented or two things must be added. This follows from the work in finite-model finding theory, and is way beyond the scope of this answer! See here for details: https://arxiv.org/abs/1706.00096)
A better use case for SBV and SMT solving for this sort of problem is to actually tell it what the add function is, and then prove some given program is correctly "compiled" using Hutton's strategy. Note that I'm explicitly saying a "given" program: It would also be very difficult to model and prove this for an arbitrary program, but you can do this rather easily for a given fixed program. If you are interested in proving the correspondence for arbitrary programs, you really should be looking at theorem provers such as Isabelle, Coq, ACL2, etc.; which can deal with induction, a proof technique you will no doubt need for this sort of problem. Note that SMT solvers cannot perform induction in general. (You can use e-matching to simulate some induction like proofs, but it's a kludge at best and in general unmaintainable.)
Here's your example, coded to prove the \x -> \y -> x + y program is "correctly" compiled and executed with respect to reference semantics:
{-# LANGUAGE ScopedTypeVariables #-}
import Data.SBV
import qualified Data.SBV.List as L
import Data.SBV.List ((.:))
-- AST Definition
data Exp = Val SWord8
| Sum Exp Exp
-- Our "Meaning" Function
eval :: Exp -> SWord8
eval (Val x) = x
eval (Sum x y) = eval x + eval y
-- Evaluation by "execution"
type Stack = SList Word8
run :: Exp -> SWord8
run e = L.head (eval' e L.nil)
where eval' :: Exp -> Stack -> Stack
eval' (Val n) s = n .: s
eval' (Sum x y) s = add (eval' y (eval' x s))
add :: Stack -> Stack
add s = v .: s''
where (a, s') = L.uncons s
(b, s'') = L.uncons s'
v = a + b
correct :: IO ThmResult
correct = prove $ do x :: SWord8 <- forall "x"
y :: SWord8 <- forall "y"
let pgm = Sum (Val x) (Val y)
spec = eval pgm
machine = run pgm
return $ spec .== machine
When I run this, I get:
*Main> correct
Q.E.D.
And the proof takes almost no time. You can easily extend this by adding other operators, binding forms, function calls, the whole works if you like. So long as you stick to a fixed "program" for verification, it should work out just fine.
If you make a mistake, let's say define add by subtraction (modify the last line of it to ready v = a - b), you get:
*Main> correct
Falsifiable. Counter-example:
x = 32 :: Word8
y = 0 :: Word8
I hope this gives an idea of what the current capabilities of SMT solvers are and how you can put them to use in Haskell via SBV.
Program synthesis is an active research area with many custom techniques and tools. An out of the box use of an SMT-solver will not get you there. But if you do build such a custom system in Haskell, you can use SBV to access an underlying SMT solver to solve many constraints you'll have to handle during the process.
(Aside: An extended example, similar in spirit but with different goals, is shipped with the SBV package: https://hackage.haskell.org/package/sbv-8.5/docs/Documentation-SBV-Examples-Strings-SQLInjection.html. This program shows how to use SBV and SMT solvers to find SQL injection vulnerabilities in an idealized SQL implementation. That might be of some interest here, and would be more aligned with how SMT solvers are typically used in practice.)
What is the best way to tuple: 1. QuickCheck inputs to a predicate with 2. the outputs returned by a tested function ?
Wanting to test (2 * 350) functions in a couple of other languages (to check for divergence from the behaviour of the Haskell base and Prelude functions which they imitate) my first experiment has been to:
capture output from (QuickCheck) verboseCheck result strings
apply the Haskell function to each of the (re-read) inputs which QuickCheck threw at it, to obtain the corresponding Haskell output
use these inputs and outputs in automated checks of the parallel functions in other languages for divergences from the behaviour of the Haskell function
For example, to get test data for a function on a list, something like:
testSet1
:: (Show a, Testable prop)
=> String -> String -> ([Int] -> a) -> prop -> IO ()
testSet1 folder fname f p = do
r <- verboseCheckResult p
let ys =
((,) <*> f) . read . listTuple1 <$>
splitOn ["Passed:"] (tail $ init $ (lines . output) r)
writeFile (concat [folder, fname, ".txt"]) (show ys)
This works OK, at least for simple cases, but I cannot immediately find ways of generalising this kind of pattern to avoid having to write a separate function (to generate and capture inputs with outputs) for every variant of type signature.
The key problem is that read typically needs some type information with which to parse the list of QuickCheck-generated inputs from their (QuickCheck result output) stringifications.
Perhaps I am taking the wrong approach. Any thoughts ? Template Haskell ?
There is a separate package to annotate properties with counterexamples (which can consist of inputs and outputs): quickcheck-with-counterexamples.
This QuickCheck issue on Github has some discussion on the same topic.
Background:
I'm doing a code translation project that requires me to generate variable names. None of the names I generate should be duplicates of each other.
I'm really frustrated since this would be stupidly simple and elegant with a Python generator function.
What I've tried:
The way I was doing it before was to pass a counter variable down through recursive calls to my translate code, and pass the (possibly incremented) counter back up in the return value of basically every function.
This was really messy: it added an extra parameter to keep track of to each of these functions; and worse still it forced me to work with messy tuple return values where I would otherwise have a simple unary return value.
I've never really gotten proficient with monads in my short time with Haskell, but I had an inkling that I could use a wrapper on the State monad to simulate a global counter variable. After 3 days of messing around trying to grok monads and make one of my own, then trying to alter someone else's monads to generate the values I needed, I've finally resigned myself to straight-up using someone else's high-level monad (perhaps with a few alterations.)
My problem now:
I've identified the MonadSupply and MonadUnique modules as a couple which likely provide the simple kind of interface I need. Unfortunately I can't figure out how to use them.
In particular the MonadSupply module documentation provides this nice example use case:
runSupplyVars x = runSupply x vars
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Looks like what I want! Once I got the module to compile I checked the type of this function in the interpreter:
> :t runSupplyVars
runSupplyVars :: Supply [Char] a -> Identity (a, [[Char]])
I've tried passing lots (hours worth) of different things to this function, with no success. I also tried passing the function to some various other functions to see if they would provide the parameters I needed implicitly. No luck so far.
The Questions:
Could someone please provide an example use case of this runSupplyVars function?
Would it be possible to do what I'm thinking with it? I want to have a function I can call from anywhere in the program, which will provide me with a different variable name or integer on each call.
To actually use the Supply monad you should structure your code with do notation and call the supply function when you actually need a name.
For example, this will produce a new variable name prefixed with var_, just to show how you might get something from the supply and use it:
newVar :: Supply [Char] [Char]
newVar = do
name <- supply
return ("var"_++name)
You'll need to structure your whole program around the Supply monad and then only call runSupplyVars once at the top-level, otherwise different parts of the program will have independent supplies and so might reuse the same variable name.
Finally, you'll need runIdentity from Control.Monad.Identity to unpack the result of runSupplyVars into the underlying tuple of type (a, [[Char]]), and then throw away the second value which is just the (infinite) list of unused names. You might be better off redefining runSupplyVars to do this for you:
import Control.Monad.Identity
[...]
runSupplyVars :: Supply [Char] a -> a
runSupplyVars x = fst (runIdentity (runSupply x vars))
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Here's a more complete example putting it all together. Note the different monads with which do notation is used - IO for the main function, and Supply [Char] for realProgram and probably most of the rest of the code in a bigger version:
import MonadSupply
import Control.Monad.Identity
main :: IO ()
main = do
let result = runSupplyVars realProgram
print result
realProgram :: Supply [Char] Int
realProgram = do
x <- newVar
return 0
newVar :: Supply [Char] [Char]
newVar = do
name <- supply
return ("var_"++name)
runSupplyVars :: Supply [Char] a -> a
runSupplyVars x = fst (runIdentity (runSupply x vars))
where vars = [replicate k ['a'..'z'] | k <- [1..]] >>= sequence
Hey haskellers and haskellettes,
is it possible to load a module functions in a list.
in my concrete case i have a list of functions all checked with or
checkRules :: [Nucleotide] -> Bool
checkRules nucs = or $ map ($ nucs) [checkRule1, checkRule2]
i do import checkRule1 and checkRule2 from a seperate module - i don't know if i will need more of them in the future.
i'd like to have the same functionality look something like
-- import all functions from Rules as rules where
-- :t rules ~~> [([Nucleotide] -> Bool)]
checkRules :: [Nucleotide] -> Bool
checkRules nucs = or $ map ($ nucs) rules
the program sorts Pseudo Nucleotide Sequences in viable and nonviable squences according to given rules.
thanks in advance ε/2
Addendum:
So do i think right - i need:
genList :: File -> TypeSignature -> [TypeSignature]
chckfun :: (a->b) -> TypeSignature -> Bool
at compile time.
but i can't generate a list of all functions in the module - as they most probably will have not the same type signature and hence not all fit in one list. so i cannot filter given list with chckfun.
In order to do this i either want to check the written type signatures in the source file (?) or the inferenced types given by the compiler(?).
another problem that comes to my mind is: not every function written in the source file might get exported ?
Is this a problem a haskell beginner should try to solve after 5 months of learning - my brain is shaped like a klein's bottle after all this "compile time thinking".
There is a nice package on Hackage just for this: language-haskell-extract. In particular, the Template Haskell function functionExtractor takes a regular expression and returns a list of the matching top level bindings as (name, value) pairs. As long as they all have matching types, you're good to go.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.Extract
myFoo = "Hello"
myBar = "World"
allMyStuff = $(functionExtractor "^my")
main = print allMyStuff
Output:
[("myFoo", "Hello"), ("myBar", "World")]
A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c