1
Fork 0
mirror of https://github.com/Jaxan/nominal-lstar.git synced 2025-04-27 22:57:45 +02:00

Uses the new NLambda features for an external teacher

This commit is contained in:
Joshua Moerman 2016-12-02 15:49:48 +01:00
parent e1b00e192b
commit 15a02c4762
2 changed files with 48 additions and 55 deletions

View file

@ -22,9 +22,8 @@ data Aut = Fifo Int | Stack Int | Running Int | NFA1 | Bollig Int
-- existential wrapper -- existential wrapper
data A = forall q i . (LearnableAlphabet i, NominalType q, Show q) => A (Automaton q i) data A = forall q i . (LearnableAlphabet i, NominalType q, Show q) => A (Automaton q i)
main :: IO () mainExample :: String -> String -> String -> IO ()
main = do mainExample learnerName teacherName autName = do
[learnerName, teacherName, autName] <- getArgs
A automaton <- return $ case read autName of A automaton <- return $ case read autName of
Fifo n -> A $ Examples.fifoExample n Fifo n -> A $ Examples.fifoExample n
Stack n -> A $ Examples.stackExample n Stack n -> A $ Examples.stackExample n
@ -40,11 +39,20 @@ main = do
NomNLStar -> learnBollig teacher NomNLStar -> learnBollig teacher
putStrLn "Finished! Final hypothesis =" putStrLn "Finished! Final hypothesis ="
print h print h
--eqs <- readIORef eqCounter
--mqs <- readIORef mqCounter mainWithIO :: String -> IO ()
--putStrLn "Number of equivalence queries:" mainWithIO learnerName = do
--print eqs let h = case read learnerName of
--putStrLn "Number of batched membership queries:" NomLStar -> learnAngluinRows teacherWithIO
--print (length mqs) NomLStarCol -> learnAngluin teacherWithIO
--putStrLn "Number of membership orbits:" NomNLStar -> learnBollig teacherWithIO
--mapM_ print $ reverse mqs putStrLn "Finished! Final hypothesis ="
print h
main :: IO ()
main = do
bla <- getArgs
case bla of
[learnerName, teacherName, autName] -> mainExample learnerName teacherName autName
[learnerName] -> mainWithIO learnerName
_ -> putStrLn "Give either 1 (for the IO teacher) or 3 (for automatic teacher) arguments"

View file

@ -13,10 +13,10 @@ import Data.List (zip, (!!), reverse)
import Data.Maybe (Maybe (..)) import Data.Maybe (Maybe (..))
import Prelude (Bool (..), Int, Read, Show, error, import Prelude (Bool (..), Int, Read, Show, error,
length, return, ($), (++), (-), (<), length, return, ($), (++), (-), (<),
(==), (.), (<=), (+), show, seq) (==), (.), (<=), (+), show, seq, (<$>))
import qualified Prelude import qualified Prelude
import Control.Monad.Identity (Identity(..)) import Control.Monad.Identity (Identity(..))
import Control.Monad (when) import Control.Monad (when, forM)
import Data.IORef (IORef, readIORef, newIORef, writeIORef) import Data.IORef (IORef, readIORef, newIORef, writeIORef)
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
@ -81,7 +81,7 @@ teacherWithTargetNonDet n aut = Teacher
-- consider the whole orbit generated by it. -- consider the whole orbit generated by it.
teacherWithIO :: Teacher Atom teacherWithIO :: Teacher Atom
teacherWithIO = Teacher teacherWithIO = Teacher
{ membership = foreachQuery ioMembership { membership = ioMembership
, equivalent = ioEquivalent , equivalent = ioEquivalent
, alphabet = atoms , alphabet = atoms
} }
@ -227,31 +227,34 @@ bisimNonDet n aut1 aut2 = runIdentity $ go empty (singleton ([], initialStates a
sumMap f = sum . (map f) sumMap f = sum . (map f)
-- Posing a membership query to the terminal and waits for used to input a formula -- Posing a membership query to the terminal and waits for used to input a formula
ioMembership :: (Show i, NominalType i) => [i] -> Formula ioMembership :: (Show i, NominalType i, Contextual i) => Set [i] -> Set ([i], Formula)
ioMembership input = unsafePerformIO $ do ioMembership inputs = unsafePerformIO $ do
let supp = leastSupport input let representedInputs = fromVariant . fromJust <$> (toList $ setOrbitsRepresentatives inputs)
Prelude.putStrLn "\n# Is the following word accepted?" Prelude.putStrLn "\n# Membership Queries:"
Prelude.putStr "# " Prelude.putStrLn "# Please answer each query with either \"True\" or \"False\""
answers <- forM representedInputs $ \input -> do
Prelude.putStr "Q: "
Prelude.print input Prelude.print input
Prelude.putStrLn "# You can answer with a formula (EQ, NEQ, AND, OR, T, F)" let loop = do
Prelude.putStrLn "# You may use the following atoms:" x <- getInputLine "A: "
Prelude.putStr "# "
Prelude.print $ zip supp [0..]
answer <- runInputT defaultSettings loop
return $ interpret supp answer
where
loop = do
x <- getInputLine "> "
case x of case x of
Nothing -> error "Quit" Nothing -> error "Bye bye, have a good day!"
Just str -> do Just str -> do
case readMaybe str :: Maybe Form of case readMaybe str :: Maybe Bool of
Nothing -> do Nothing -> do
outputStrLn $ "Unable to parse " ++ str ++ " :: Form" outputStrLn $ "Unable to parse " ++ str ++ " :: Bool"
loop loop
Just f -> return f Just f -> return f
answer <- runInputT defaultSettings loop
Prelude.print $ orbit [] (input, fromBool answer)
return $ orbit [] (input, fromBool answer)
let answersAsSet = sum . fromList $ answers
Prelude.putStrLn "\n# Thanks!"
Prelude.print answersAsSet
return answersAsSet
-- Poses a query to the terminal, waiting for the user to provide a counter example -- Poses a query to the terminal, waiting for the user to provide a counter example
-- TODO: extend to any alphabet type (hard because of parsing)
ioEquivalent :: (Show q, NominalType q) => Automaton q Atom -> Maybe (Set [Atom]) ioEquivalent :: (Show q, NominalType q) => Automaton q Atom -> Maybe (Set [Atom])
ioEquivalent hypothesis = unsafePerformIO $ do ioEquivalent hypothesis = unsafePerformIO $ do
Prelude.putStrLn "\n# Is the following automaton correct?" Prelude.putStrLn "\n# Is the following automaton correct?"
@ -282,21 +285,3 @@ ioEquivalent hypothesis = unsafePerformIO $ do
outputStrLn $ "Unable to parse " ++ str ++ " :: Maybe [String]" outputStrLn $ "Unable to parse " ++ str ++ " :: Maybe [String]"
loop loop
Just f -> return f Just f -> return f
-- Data structure for reading formulas (with the derived Read instance)
data Form
= EQ Int Int
| NEQ Int Int
| AND Form Form
| OR Form Form
| T
| F
deriving (Read)
interpret :: [Atom] -> Form -> Formula
interpret support (EQ i j) = eq (support !! i) (support !! j)
interpret support (NEQ i j) = neq (support !! i) (support !! j)
interpret support (AND f1 f2) = interpret support f1 /\ interpret support f2
interpret support (OR f1 f2) = interpret support f1 \/ interpret support f2
interpret _ T = true
interpret _ F = false