Hare/Setup.hs
Hare/Tests.hs
Hare/Untyped.hs
Hare/Hare.cabal
Hare/HareMonad.hs
Hare/stack.yaml
Hare/Hare.hs
Hare/Tests/Transcript.hs
Hare/Tests/Support.hs
Hare/Tests/Examples.hs
Hare/Tests/UnitTests.hs
Hare/Tests/transcript.txt
— Generated by Haskell for Mac for standalone builds
import Distribution.Simple
main = defaultMain
module Main where
import Test.Tasty (defaultMain, testGroup)
import Tests.Transcript
import Tests.UnitTests
import Tests.Examples
tests = testGroup “all tests” [
testGroup “transcript acceptance tests” [
testGroup “basic match tests” [
test_empty, test_fail, test_courseCodesRaw, test_grades, test_firstname
],
testGroup “action tests” [
test_courseCodes, test_grades
],
testGroup “combinator tests” [
test_decimalNumber, test_gradeRecords, test_tortoiseCourseCodes,
test_gradesAlt, test_studentNumber, test_stars
]
],
testGroup “unit tests and properties” [
testGroup “empty” [ test_empty_maybe, test_empty_list ],
testGroup “fail” [ test_fail_maybe, test_fail_list ],
testGroup “char” [ test_char_filter, test_char_maybe ],
testGroup “seq” [ test_seq_1, test_seq_2, test_seq_3, test_seq_4, test_seq_5],
testGroup “cho” [ test_ch_1, test_ch_2, test_ch_3, test_ch_4, test_ch_5],
testGroup “star” [ test_star_1,test_star_2, test_star_3]
],
testGroup “spec examples” [
testGroup “action” [test_action_ex_1, test_action_ex_2, test_action_ex_3 ],
testGroup “cons” [test_cons_ex_1, test_cons_ex_2],
testGroup “plus” [test_plus_ex_1, test_plus_ex_2],
testGroup “string” [test_string_ex_1, test_string_ex_2],
testGroup “choose” [test_choose_ex_1, test_choose_ex_2],
testGroup “option” [test_option_ex_1, test_option_ex_2],
testGroup “rpt” [test_rpt_ex_1, test_rpt_ex_2],
testGroup “rptRange” [test_rptRange_ex_1, test_rptRange_ex_2]
]
]
main = defaultMain tests
{-# LANGUAGE GADTs, DataKinds, KindSignatures, PolyKinds, TypeOperators, TypeFamilies, ScopedTypeVariables #-}
module Untyped where
import Control.Applicative
import HareMonad (Hare, hare, failure, readCharacter)
import Control.Monad(guard)
data RE = Empty
| Fail
| Char [Char]
| Seq RE RE
| Choose RE RE
| Star RE
data Results = None
| Character Char
| Tuple Results Results
| Repetition [Results]
deriving (Show)
match :: (Monad f, Alternative f) => RE -> Hare f Results
match Empty = pure None
match Fail = failure
match (Char cs) = do
x <- readCharacter
guard (x `elem` cs)
pure (Character x)
match (Seq a b) = do
ra <- match a
rb <- match b
pure (Tuple ra rb)
match (Choose a b) =
match a
<|> match b
match (Star a) =
addFront <$> match a <*> match (Star a)
<|> pure (Repetition [])
where
addFront x (Repetition xs) = Repetition (x:xs)
addFront _ _ = error “(should be) impossible!”
(=~) :: (Monad f, Alternative f) => String -> RE -> f Results
str =~ re = hare matchAnywhere str
where matchAnywhere = match re <|> (readCharacter >> matchAnywhere)
name: Hare
version: 1.0
cabal-version: >=1.11
build-type: Simple
license: AllRightsReserved
stability: experimental
data-files:
Untyped.hs
Tests/transcript.txt
x-ghc-framework-version: 8.0.2-8.9-3
x-last-ide-version: HfM1.5.1
Executable HareTests
main-is: Tests.hs
buildable: True
build-depends:
base -any,
QuickCheck -any,
tasty -any,
tasty-quickcheck -any,
tasty-hunit -any,
transformers -any,
mtl -any
default-language: Haskell2010
other-modules:
Hare
HareMonad
Tests.UnitTests
Tests.Support
Tests.Transcript
Tests.Examples
module HareMonad
( Hare
, hare
, failure
, readCharacter
) where
import Control.Applicative
newtype Hare f a
= Hare { runHare :: String -> f (String, a) }
hare :: Functor f => Hare f a -> String -> f a
hare a s = fmap snd (runHare a s)
instance Functor f => Functor (Hare f) where
fmap f (Hare a) = Hare $ \s ->
fmap (fmap f) (a s)
instance Monad f => Applicative (Hare f) where
pure x = Hare $ \s -> pure (s, x)
Hare f <*> Hare x = Hare $ \s -> do
(s’,rf) <- f s
(s'',rx) <- x s'
return (s'', rf rx)
instance Monad f => Monad (Hare f) where
return x = pure x
Hare a >>= f = Hare $ \s -> do
(s’, ra) <- a s
let (Hare f') = f ra
(s'', rf) <- f' s'
pure (s'', rf)
instance (Monad f, Alternative f) => Alternative (Hare f) where
empty = Hare (const empty)
Hare a <|> Hare b = Hare $ \s -> a s <|> b s
failure :: (Alternative f, Monad f) => Hare f a
failure = empty
readCharacter :: (Alternative f, Monad f) => Hare f Char
readCharacter = Hare $ \s -> case s of
[] -> empty
(x:xs) -> pure (xs,x)
# This file was automatically generated by ‘stack init’
#
# Some commonly used options have been documented as comments in this file.
# For advanced use and comprehensive documentation of the format, please see:
# https://docs.haskellstack.org/en/stable/yaml_configuration/
# Resolver to choose a ‘specific’ stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
# resolver: ghcjs-0.1.0_ghc-7.10.2
# resolver:
# name: custom-snapshot
# location: “./custom-snapshot.yaml”
resolver: lts-9.14
# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# – some-directory
# – https://example.com/foo/bar/baz-0.0.2.tar.gz
# – location:
# git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# – location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# extra-dep: true
# subdirs:
# – auto-update
# – wai
#
# A package marked ‘extra-dep: true’ will only be built if demanded by a
# non-dependency (i.e. a user package), and its test suites and benchmarks
# will not be run. This is useful for tweaking upstream packages.
packages:
– .
# Dependency packages to be pulled from upstream that are not in the resolver
# (e.g., acme-missiles-0.3)
extra-deps:
# Override default flag values for local packages and extra-deps
flags: {}
# Extra package databases containing global packages
extra-package-dbs: []
# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: “>=1.5”
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor
{-# LANGUAGE GADTs, DataKinds, KindSignatures, TupleSections, PolyKinds, TypeOperators, TypeFamilies, PartialTypeSignatures #-}
module Hare where
import Control.Monad
import Control.Applicative
import HareMonad
data RE :: * -> * where
Empty :: RE ()
Fail :: RE a
— Char
— Seq
— Choose
— Star
Action :: (a -> b) -> RE a -> RE b
match :: (Alternative f, Monad f) => RE a -> Hare f a
match re = error “‘match’ unimplemented”
matchAnywhere :: (Alternative f, Monad f) => RE a -> Hare f a
matchAnywhere re = match re <|> (readCharacter >> matchAnywhere re)
(=~) :: (Alternative f, Monad f) => String -> RE a -> f a
(=~) = flip (hare . matchAnywhere)
infixr `cons`
cons :: RE a -> RE [a] -> RE [a]
cons x xs = error “‘cons’ unimplemented”
string :: String -> RE String
string xs = error “‘string’ unimplemented”
rpt :: Int -> RE a -> RE [a]
rpt n re = error “‘rpt’ unimplemented”
rptRange :: (Int, Int) -> RE a -> RE [a]
rptRange (x,y) re = error “‘rptRange’ unimplemented”
option :: RE a -> RE (Maybe a)
option re = error “‘option’ unimplemented”
plus :: RE a -> RE [a]
plus re = error “‘plus’ unimplemented”
choose :: [RE a] -> RE a
choose res = error “‘choose’ unimplemented”
module Tests.Transcript where
import Hare
import Tests.Support
import Data.List(inits,reverse)
data GradeRecord = R String (Maybe Int) String deriving (Eq,Show)
reDecimalNumber
= wrap $ Action (\((w,p),d) -> read (w ++ p : d) :: Double) $
plus digits `Seq` Char [‘.’] `Seq` plus digits
where
digits = Char [‘0’..’9′]
— Expect spaces before and after to remove partial matches
— Gets rid of numbers at the end of lines too but meh.
wrap re = Action (\((_,r),_) -> r) (Char [‘ ‘] `Seq` re `Seq` Char [‘ ‘])
reStudentNumber
= rpt 7 (Char [‘0’..’9′])
reGradeRecords
= Action (\((c,m),g) -> R c m g) $
(reCourseCodes `seqFst` Star printable)
`Seq` (reDecimalNumber `Seq` spaces `Seq` reDecimalNumber `Seq` spaces
`seqSnd` option (numbers `seqFst` spaces))
`Seq` reGrades
where
printable = Char [‘ ‘..’~’] — every printable ASCII character.
spaces = Star (Char [‘ ‘])
seqFst :: RE a -> RE b -> RE a
seqFst a b = Action fst (a `Seq` b)
seqSnd :: RE a -> RE b -> RE b
seqSnd a b = Action snd (a `Seq` b)
numbers :: RE Int
numbers = Action read (plus (Char [‘0’..’9′]))
reStars = Char [‘ ‘] `seqSnd` rptRange (1,10) (Char [‘*’]) `seqFst` Char [‘\n’]
where
seqFst :: RE a -> RE b -> RE a
seqFst a b = Action fst (a `Seq` b)
seqSnd :: RE a -> RE b -> RE b
seqSnd a b = Action snd (a `Seq` b)
reCourseCodesRaw = caps `Seq` caps `Seq` caps `Seq` caps
`Seq` digits `Seq` digits `Seq` digits `Seq` digits
where caps = Char [‘A’..’Z’]
digits = Char [‘0’..’9′]
reCourseCodes = Action fromRaw reCourseCodesRaw
where fromRaw ((((((((c,o),m),p),a),b),x),y)) = [c,o,m,p,a,b,x,y]
reGradesRaw = (Char [‘H’] `Seq` Char [‘D’])
`Choose` (Char [‘D’] `Seq` Char [‘N’])
`Choose` (Char [‘C’] `Seq` Char [‘R’])
`Choose` (Char [‘P’] `Seq` Char [‘S’])
`Choose` (Char [‘F’] `Seq` Char [‘L’])
`Choose` (Char [‘A’] `Seq` Char [‘F’])
`Choose` (Char [‘S’] `Seq` Char [‘Y’])
`Choose` (Char [‘E’] `Seq` Char [‘C’])
`Choose` (Char [‘R’] `Seq` Char [‘C’])
reGrades = Action fromRaw reGradesRaw
where fromRaw (a,b) = [a,b]
reTortoiseCourseCodes = Action fst (reCourseCodes `Seq` string ” Tortoise”)
reGradesAlt = choose
[ string “HD”
, string “DN”
, string “CR”
, string “PS”
, string “FL”
, string “AF”
, string “SY”
, string “EC”
, string “RC”
]
test_empty = testRE “Empty” Empty “Tests/transcript.txt” (replicate 5102 ())
test_fail = testRE “Fail” (Fail :: RE ()) “Tests/transcript.txt” []
test_courseCodesRaw
= testRE “raw course codes (Seq, Char)”
reCourseCodesRaw “Tests/transcript.txt” (map toRaw transcriptCodes)
where
toRaw [c,o,m,p,a,b,x,y] = ((((((((c,o),m),p),a),b),x),y))
test_courseCodes
= testRE “course codes (Seq, Char, Action)”
reCourseCodes “Tests/transcript.txt” transcriptCodes
test_tortoiseCourseCodes
= testRE “course codes for names starting with Tortoise (string)”
reTortoiseCourseCodes “Tests/transcript.txt”
[“SHEL1603″,”TORT1927″,”TORT4181″,”TORT4418”]
test_gradesRaw
= testRE “raw grades (Seq, Char, Choose)”
reGradesRaw “Tests/transcript.txt” (map toRaw transcriptGrades)
where
toRaw [a,b] = (a,b)
test_grades
= testRE “raw grades (Seq, Char, Choose, Action)”
reGrades “Tests/transcript.txt” transcriptGrades
test_gradesAlt
= testRE “grades using combinators (string, choose)”
reGradesAlt “Tests/transcript.txt” transcriptGrades
test_firstname
= testRE “first name inits (Char, Seq, Star)”
regex “Tests/transcript.txt” expected
where regex = (Char [‘,’] `Seq` Star printable)
printable = Char [‘ ‘..’~’] — every printable ASCII character.
expected = map ((,) ‘,’) (reverse (inits ” Simon The”))
test_gradeRecords
= testRE “grade records (option, plus)”
reGradeRecords “Tests/transcript.txt” transcriptGradeRecords
test_decimalNumber
= testRE “decimal numbers (plus)”
reDecimalNumber “Tests/transcript.txt” transcriptDecimalNumbers
test_studentNumber
= testRE “student number (rpt)”
reStudentNumber “Tests/transcript.txt” [“4444444”]
test_stars
= testRE “stars (rptRange)”
reStars “Tests/transcript.txt”
[“********”,”******”,”********”,”****”,”****”,”*****”,”******”
,”********”,”*****”,”*****”,”****”]
transcriptCodes =
[ “TORT1917”, “SHEL1603”, “TURT1000”, “MATH1131”,
“TORT1927”, “TURT1001”, “MATH1231”,
“TURT2630”, “TORT2041”, “TORT2121”, “TORT2911”,
“TURT2631”, “TORT3161”,
“COMP3141”, “TORT3901”,
“TORT3151”, “TORT4181”,
“TORT3131”, “TORT3411”, “TORT4141”,
“TORT3171”, “TORT4161”, “TORT4418”, “MATH1081”,
“TORT3891”, “TORT4910”, “TORT6721”,
“TORT4911”, “TORT4920”,
“TORT3902”,
“TORT6752”, “TORT9153”, “TORT9902”,
“TORT9902”, “GSOE9400”,
“TORT9902”, “GSOE9400”,
“TORT9902”,
“TORT9902”,
“TORT9902”,
“TORT9902”,
“TORT9902” ]
transcriptGrades =
[“HD”,”CR”,”DN”,”PS”
,”HD”,”PS”,”PS”
,”PS”,”HD”,”CR”,”HD”
,”PS”,”HD”
,”HD”,”HD”
,”HD”,”HD”
,”HD”,”DN”,”CR”
,”HD”,”HD”,”HD”,”PS”
,”HD”,”SY”,”HD”
,”HD”,”DN”
,”HD”
,”HD”,”HD”,”RC”
,”RC”,”EC”
,”RC”,”SY”
,”RC”,”RC”,”RC”,”RC”,”RC”]
transcriptDecimalNumbers =
[6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,76.75,24.0
,6.0,6.0,6.0,6.0,6.0,6.0,71.0,42.0
,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,76.0,24.0
,6.0,6.0,6.0,6.0,72.5,12.0
,6.0,6.0,6.0,6.0,95.5,12.0
,6.0,6.0,6.0,6.0,90.5,12.0
,6.0,6.0,6.0,6.0,6.0,6.0,78.333,18.0
,6.0,6.0,6.0,6.0,6.0,6.0,6.0,6.0,82.75,24.0
,6.0,6.0,3.0,3.0,6.0,6.0,86.5,15.0
,15.0,15.0,6.0,6.0,90.0,21.0
,12.0,12.0,93.0,12.0
,82.691,192.0
,0.0,0.0,0.0,0.0,24.0,0.0,24.0
,24.0,0.0,0.0,0.0,24.0
,24.0,0.0,0.0,0.0,24.0
,24.0,0.0,24.0
,24.0,0.0,24.0
,24.0,0.0,24.0
,24.0,0.0,24.0
,24.0,0.0,24.0
,0.0,192.0]
transcriptGradeRecords =
[R “TORT1917” (Just 94) “HD”,R “SHEL1603” (Just 74) “CR”
,R “TURT1000” (Just 80) “DN”,R “MATH1131” (Just 59) “PS”
,R “TORT1927” (Just 98) “HD”,R “TURT1001” (Just 58) “PS”
,R “MATH1231” (Just 57) “PS”,R “TURT2630” (Just 56) “PS”
,R “TORT2041” (Just 90) “HD”,R “TORT2121” (Just 69) “CR”
,R “TORT2911” (Just 89) “HD”,R “TURT2631” (Just 54) “PS”
,R “TORT3161” (Just 91) “HD”,R “COMP3141” (Just 93) “HD”
,R “TORT3901” (Just 98) “HD”,R “TORT3151” (Just 87) “HD”
,R “TORT4181” (Just 94) “HD”,R “TORT3131” (Just 89) “HD”
,R “TORT3411” (Just 75) “DN”,R “TORT4141” (Just 71) “CR”
,R “TORT3171” (Just 85) “HD”,R “TORT4161” (Just 100) “HD”
,R “TORT4418” (Just 86) “HD”,R “MATH1081” (Just 60) “PS”
,R “TORT3891” (Just 86) “HD”,R “TORT4910” Nothing “SY”
,R “TORT6721” (Just 87) “HD”,R “TORT4911” (Just 96) “HD”
,R “TORT4920” (Just 75) “DN”,R “TORT3902” (Just 93) “HD”
,R “TORT6752” (Just 89) “HD”,R “TORT9153” (Just 86) “HD”
,R “TORT9902” Nothing “RC”,R “TORT9902” Nothing “RC”
,R “GSOE9400” Nothing “EC”,R “TORT9902” Nothing “RC”
,R “GSOE9400” Nothing “SY”,R “TORT9902” Nothing “RC”
,R “TORT9902” Nothing “RC”,R “TORT9902” Nothing “RC”
,R “TORT9902” Nothing “RC”,R “TORT9902” Nothing “RC”]
module Tests.Support where
import Test.Tasty (TestName, TestTree)
import Test.Tasty.HUnit
import Hare
testRE :: (Eq a, Show a) => TestName -> RE a -> FilePath -> [a] -> TestTree
testRE n re fp rs =
testCase n $ do
corpus <- readFile fp
assertEqual "" rs (corpus =~ re)
assertEq :: (Eq a, Show a) => a -> a -> Assertion
assertEq = flip (assertEqual “”)
module Tests.Examples where
import Data.List
import Tests.Support
import Test.Tasty.HUnit
import Hare
import Data.Char
import Data.Maybe
test_action_ex_1 = testCase “action example 1” $
assertEq (“***” =~ Action length (Star (Char [‘*’])))
[3,2,1,0,2,1,0,1,0,0]
test_action_ex_2 = testCase “action example 2” $
assertEq (“AXax” =~ Action isUpper (Char [‘a’,’A’]))
[True, False]
test_action_ex_3 = testCase “action example 3” $ do
let f (x,y) = [x,y]
let atoz = Char [‘a’..’z’]
assertEq (“ab01cd20” =~ Action f (atoz `Seq` atoz)) [“ab”,”cd”]
test_cons_ex_1 = testCase “cons example 1” $ do
assertEq (“10100” =~ cons (Char [‘1’]) (Star (Char [‘0’])))
[“10″,”1″,”100″,”10″,”1”]
test_cons_ex_2 = testCase “cons example 2” $ do
assertEq (“10100” =~ cons (Char [‘1’]) (Action (const []) Empty))
[“1″,”1”]
test_plus_ex_1 = testCase “plus example 1” $ do
assertEq (“10100” =~ plus (Char [‘0’]))
[“0″,”00″,”0″,”0”]
test_plus_ex_2 = testCase “plus example 2” $ do
let atoz = Char [‘a’..’z’]
let digits = Char [‘0’..’9′]
assertEq (“ab1c3” =~ plus (atoz `Seq` digits))
[[(‘b’,’1′),(‘c’,’3′)],[(‘b’,’1′)],[(‘c’,’3′)]]
test_string_ex_1 = testCase “string example 1” $ do
let comp3141 = string “COMP3141”
assertEq (“My favourite subject is COMP3141” =~ comp3141) (Just “COMP3141”)
test_string_ex_2 = testCase “string example 2” $ do
let comp3141 = string “COMP3141”
assertEq (“My favourite subject is MATH1141” =~ comp3141) Nothing
test_choose_ex_1 = testCase “choose example 1” $ do
let re = choose [string “COMP”, string “MATH”, string “PHYS”]
assertEq (“COMP3141, MATH1081, PHYS1121, COMP3121” =~ re)
[“COMP”,”MATH”,”PHYS”,”COMP”]
test_choose_ex_2 = testCase “choose example 2” $ do
assertEq (“abc” =~ choose []) (Nothing :: Maybe String)
test_option_ex_1 = testCase “option example 1” $ do
let digits = Char [‘0’..’9′]
let sign = Action (fromMaybe ‘+’) (option (Char [‘-‘]))
assertEq (“-30 5 3” =~ (sign `cons` plus digits))
[“-30″,”-3″,”+30″,”+3″,”+0″,”+5″,”+3″]
test_option_ex_2 = testCase “option example 2” $ do
assertEq (“foo” =~ option (Char [‘a’]))
[Nothing, Nothing, Nothing, Nothing]
test_rpt_ex_1 = testCase “rpt example 1” $ do
let digits = Char [‘0’..’9′]
let programs = choose [string “COMP”, string “PHYS”, string “MATH”]
let courseCode = programs `Seq` rpt 4 digits
assertEq (“COMP3141, MATH1081, and PHYS1121” =~ courseCode)
[(“COMP”,”3141″),(“MATH”,”1081″),(“PHYS”,”1121″)]
test_rpt_ex_2 = testCase “rpt example 2” $ do
assertEq (“foo” =~ rpt 0 (Char [‘a’]))
(Just “”)
test_rptRange_ex_1 = testCase “rptRange example 1” $ do
assertEq (“1234” =~ rptRange (2,4) (Char [‘0’..’9′]))
[“1234″,”123″,”12″,”234″,”23″,”34”]
test_rptRange_ex_2 = testCase “rptRange example 2” $ do
assertEq (“1234” =~ rptRange (3,3) (Char [‘0’..’9′]))
[“123″,”234”]
{-# LANGUAGE TupleSections #-}
module Tests.UnitTests where
import Data.List
import Test.Tasty.QuickCheck
import Hare
test_empty_maybe = testProperty “empty (maybe)” $
\s -> (s =~ Empty) == Just ()
test_empty_list = testProperty “empty (list)” $
\s -> (s =~ Empty) == replicate (length s + 1) ()
test_fail_maybe = testProperty “fail (maybe)” $
\s -> (s =~ Fail) == (Nothing :: Maybe ())
test_fail_list = testProperty “fail (list)” $
\s -> (s =~ Fail) == ([] :: [()])
test_char_filter = testProperty “char (list) is like filter” $
\s xs -> (s =~ Char xs) == filter (`elem` xs) s
test_char_maybe = testProperty “char (maybe)” $
\s c -> ((s =~ Char [c]) == Just c) == (c `elem` s)
test_seq_1 = testProperty “fail in seq 1” $
\s c -> (s =~ (Fail `Seq` Char c)) == ([] :: [((), Char)])
test_seq_2 = testProperty “fail in seq 2” $
\s c -> (s =~ (Char c `Seq` Fail)) == ([] :: [(Char, ())])
test_seq_3 = testProperty “empty in seq 1” $
\s c -> (s =~ (Empty `Seq` Char c)) == map (() ,) (s =~ Char c)
test_seq_4 = testProperty “empty in seq 2” $
\s c -> (s =~ (Char c `Seq` Empty)) == map (, ()) (s =~ Char c)
test_seq_5 = testProperty “two chars in seq” $
\s c1 c2 -> case (s =~ (Char c1 `Seq` Char c2)) of
Nothing -> not $ any (`substring` s) [ [a,b] | a <- c1, b <- c2]
Just (a,b) -> [a,b] `substring` s
test_ch_1 = testProperty “fail in choose 1” $
\s c -> ((s =~ Char c) :: [Char]) == (s =~ (Char c `Choose` Fail))
test_ch_2 = testProperty “fail in choose 2” $
\s c -> ((s =~ Char c) :: [Char]) == (s =~ (Fail `Choose` Char c))
test_ch_3 = testProperty “two chars in choose” $
\s c1 c2 -> ((s =~ (Char c1 `Choose` Char c2)) :: Maybe Char) == (s =~ Char (c1 ++ c2))
test_ch_4 = testProperty “choose and seq 1” $
\s c1 c2 c3 -> ((s =~ (Char c1 `Seq` (Char c2 `Choose` Char c3))) :: [(Char,Char)])
== ((s =~ ((Char c1 `Seq` Char c2) `Choose` (Char c1 `Seq` Char c3))))
test_ch_5 = testProperty “choose and seq 2” $
\s c1 c2 c3 -> ((s =~ ((Char c2 `Choose` Char c3) `Seq` Char c1)) :: [(Char,Char)])
== ((s =~ ((Char c2 `Seq` Char c1) `Choose` (Char c3 `Seq` Char c1))))
test_star_1 = testProperty “star replicate” $
\n c -> let s = replicate n c in sort (s =~ Star (Char [c])) == sort (concatMap inits (inits s))
test_star_2 = testProperty “star fail” $
\s -> ((s =~ Star Fail) :: [[()]]) == replicate (length s + 1) []
test_star_3 = testProperty “star char” $
\s c -> (all (== []) ((s =~ Star (Char c)) :: [String]))
== not (any (`elem` c) s)
substring :: String -> String -> Bool
substring x y = any (x `isPrefixOf`) (tails y)
Name: Tortoise, Simon The
Student ID: 4444444
Academic Career 1 of 2: Undergraduate
Program: Tortoise Science
26/02/2013: Completed Program
26/02/2013: Tortoise Science Honours
Beginning of Undergraduate Record
Semester 1 2008
UOCs: ********
2008 S1 TORT1917 Higher Tortoising 1 6.00 6.00 94 HD
2008 S1 SHEL1603 Tortoise Shell Cleaning 6.00 6.00 74 CR
2008 S1 TURT1000 Turtlese Communication 1A 6.00 6.00 80 DN
2008 S1 MATH1131 Mathematics 1A 6.00 6.00 59 PS
Term WAM: 76.750 Term Totals 24.00 24.00
Good Standing
Semester 2 2008
UOCs: ******
2008 S2 TORT1927 Tortoise Graphics and Algos 6.00 6.00 98 HD
2008 S2 TURT1001 Turtlese Communication 1B 6.00 6.00 58 PS
2008 S2 MATH1231 Mathematics 1B 6.00 6.00 57 PS
Term WAM: 71.000 Term Totals 42.00 42.00
Good Standing
Semester 1 2009
UOCs: ********
2009 S1 TURT2630 Intermediate Turtlese A 6.00 6.00 56 PS
2009 S1 TORT2041 Bash Tortoise Shells 6.00 6.00 90 HD
2009 S1 TORT2121 Looking Under the Shell 6.00 6.00 69 CR
2009 S1 TORT2911 Eng. Design in Tortoising 6.00 6.00 89 HD
Term WAM: 76.000 Term Totals 24.00 24.00
Good Standing
Semester 2 2009
UOCs: ****
2009 S2 TURT2631 Intermediate Turtlese B 6.00 6.00 54 PS
2009 S2 TORT3161 Concepts of Tortoising Lang. 6.00 6.00 91 HD
Term WAM: 72.500 Term Totals 12.00 12.00
Good Standing
Semester 1 2010
UOCs: ****
2010 S1 COMP3141 Software Sys Des&Implementat’n 6.00 6.00 93 HD
2010 S1 TORT3901 Special Project A 6.00 6.00 98 HD
Term WAM: 95.500 Term Totals 12.00 12.00
Good Standing
Semester 2 2010
UOCs: *****
2010 S2 TORT3151 Byzantine Tortoises 6.00 6.00 87 HD
2010 S2 TORT4181 Tortoise-based Software Safety 6.00 6.00 94 HD
Term WAM: 90.500 Term Totals 12.00 12.00
Good Standing
Semester 1 2011
UOCs: ******
2011 S1 TORT3131 Tortoising Languages & Compilers 6.00 6.00 89 HD
2011 S1 TORT3411 Artificial Tortoise Intelligence 6.00 6.00 75 DN
2011 S1 TORT4141 Theory of Tortoising 6.00 6.00 71 CR
Term WAM: 78.333 Term Totals 18.00 18.00
Good Standing
Semester 2 2011
UOCs: ********
2011 S2 TORT3171 Turtle-Oriented Programming 6.00 6.00 85 HD
2011 S2 TORT4161 Advanced Tortoisification 6.00 6.00 100 HD
2011 S2 TORT4418 Tortoise Representation 6.00 6.00 86 HD
2011 S2 MATH1081 Discrete Mathematics 6.00 6.00 60 PS
Term WAM: 82.750 Term Totals 24.00 24.00
Good Standing
Semester 1 2012
UOCs: *****
2012 S1 TORT3891 Ext Tortoise Systems 6.00 6.00 86 HD
2012 S1 TORT4910 Thesis Part A 3.00 3.00 SY
2012 S1 TORT6721 (In-)Formal Tortoises 6.00 6.00 87 HD
Term WAM: 86.500 Term Totals 15.00 15.00
Good Standing
Semester 2 2012
UOCs: *****
2012 S2 TORT4911 Thesis Part B 15.00 15.00 96 HD
2012 S2 TORT4920 Management and Tortoises 6.00 6.00 75 DN
Term WAM: 90.000 Term Totals 21.00 21.00
Good Standing
Summer Semester 2013
UOCs: ****
2013 X1 TORT3902 Special Project B 12.00 12.00 93 HD
Term WAM: 93.000 Term Totals 12.00 12.00
3983 Science/Tortoise Science Totals
WAM: 82.691 Units: 192.00 192.00
Academic Career 2 of 2: Research
Print Date: 10/12/2017
Program: Tortoise Science and Eng
04/11/2013: Prematriculant
04/11/2013: Tortoise Science and Engineering Research
Beginning of Research Record
Semester 1 2014
2014 S1 TORT6752 Modelling Concurrent Tortoises 0.00 0.00 89 HD
2014 S1 TORT9153 Algorithmic Tortoisification 0.00 0.00 86 HD
2014 S1 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
Semester 2 2014
2014 S2 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
2014 S2 GSOE9400 Engineering Pgrad Research 0.00 0.00 EC
Term Totals 24.00 0.00
Semester 1 2015
2015 S1 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
2015 S1 GSOE9400 Engineering Pgrad Research 0.00 0.00 SY
Term Totals 24.00 0.00
Semester 2 2015
2015 S2 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
Semester 1 2016
2016 S1 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
Semester 2 2016
2016 S2 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
Semester 1 2017
2017 S1 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
Semester 2 2017
2017 S2 TORT9902 Res. Thesis Tort Sci & Eng F/T 24.00 0.00 RC
Term Totals 24.00 0.00
1650 Tortoise Science and Eng Totals
WAM: 0.000 Units: 192.00 0.00