Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delayed parsing #125

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion logic-tasks.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.35.0.
-- This file has been generated from package.yaml by hpack version 0.36.0.
--
-- see: https://github.com/sol/hpack

Expand Down Expand Up @@ -54,6 +54,7 @@ library
Trees.Helpers
Trees.Generate
Formula.Parsing
Formula.Parsing.Delayed
Formula.Helpers
ParsingHelpers
Config
Expand Down
2 changes: 2 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies:
- text
- output-monad
- pretty-simple
- parsec
- latex-svg-image >= 0.2
- bytestring
- utf8-string
Expand Down Expand Up @@ -70,6 +71,7 @@ library:
- Trees.Helpers
- Trees.Generate
- Formula.Parsing
- Formula.Parsing.Delayed
- Formula.Helpers
- ParsingHelpers
- Config
Expand Down
7 changes: 6 additions & 1 deletion src/Formula/Parsing.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ instance Parse a => Parse [a] where
tokenSymbol "]" <|> fail "could not parse an enclosing ']'"
pure xs


instance (Parse a, Parse b) => Parse (a,b) where
parser = between (tokenSymbol "(") (tokenSymbol ")") $ do
a <- parser
tokenSymbol ","
b <- parser
pure (a,b)

instance Parse Number where
parser = (lexeme numParse <?> "Number") <|> fail "Could not parse a number"
Expand Down
31 changes: 31 additions & 0 deletions src/Formula/Parsing/Delayed.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DeriveGeneric #-}
module Formula.Parsing.Delayed where


import Text.Parsec
import Text.Parsec.String (Parser)
import ParsingHelpers (fully)

import Control.Monad.Output (LangM, english, german, OutputMonad)

import LogicTasks.Helpers (reject)

import Data.Typeable (Typeable)
import GHC.Generics (Generic)

newtype Delayed a = Delayed String deriving (Eq, Show, Typeable, Generic)

delayed :: String -> Delayed a
delayed = Delayed

parseDelayed :: Delayed a -> Parser a -> Either ParseError a
parseDelayed (Delayed str) p = parse p "(delayed input)" str
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taucht dieses "(delayed input)" dann eigentlich in den anzuzeigenden Fehlermeldungen auf? Für die Studierenden wäre der Begriff sicher verwirrend.

Copy link
Member Author

@owestphal owestphal Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja tut es. In erster Linie wollte ich damit das Debuggen von Parserfehlern einfacher machen. Kann schon sein, dass das verwirrend ist. Ich denke aber, dass es erkennbar sein sollte, dass der Fehler aus dem verzögerten Parsen entsteht (evtl sogar aus welcher Phase genau, bei mehreren?). Vieleicht ist eine Formulierung besser, die Studierende eher als "neutrales Element" im Fehlerstring lesen. Evtl. "(task-parser-input)" oder "(answer string)"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wahrscheinlich ist "(answer string)" ganz gut.


withDelayed :: OutputMonad m => (a -> LangM m) -> Parser a -> Delayed a -> LangM m
withDelayed grade p d =
case parseDelayed d (fully p) of
Left err -> reject $ do
english $ show err
german $ show err
Right x -> grade x
5 changes: 0 additions & 5 deletions src/LogicTasks/Semantics/Fill.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import LogicTasks.Helpers (example, extra)
import Data.Foldable.Extra (notNull)




genFillInst :: FillConfig -> Gen FillInst
genFillInst FillConfig{ cnfConf = CnfConfig { baseConf = BaseConfig{..}, ..}, ..} = do
cnf <- cnfInRange
Expand Down Expand Up @@ -114,8 +112,6 @@ verifyQuiz FillConfig{..}
start :: [TruthValue]
start = []



partialGrade :: OutputMonad m => FillInst -> [TruthValue] -> LangM m
partialGrade FillInst{..} sol = do
preventWithHint (solLen /= missingLen)
Expand All @@ -134,7 +130,6 @@ partialGrade FillInst{..} sol = do
solLen = length boolSol
missingLen = length missing


completeGrade :: OutputMonad m => FillInst -> [TruthValue] -> LangM m
completeGrade FillInst{..} sol = do
preventWithHint (notNull diff)
Expand Down
17 changes: 10 additions & 7 deletions src/LogicTasks/Semantics/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import Formula.Types (Cnf, Formula, Literal(..), amount, atomics, genCnf, getCla
import LogicTasks.Helpers (formulaKey, example, extra)
import Util (checkTruthValueRange, pairwiseCheck, prevent, preventWithHint, tryGen, withRatio)
import Control.Monad (when)

import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))



Expand Down Expand Up @@ -168,10 +169,11 @@ partialMinMax correctLits correct solution allValidTerms isMaxTermTask = do
then ("Maxterme", "Klauseln", "maxterms", "clauses") -- no-spell-check
else ("Minterme", "Konjunktionen", "minterms", "conjunctions") -- no-spell-check

partialGrade :: OutputMonad m => MaxInst -> Delayed Cnf -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser


partialGrade :: OutputMonad m => MaxInst -> Cnf -> LangM m
partialGrade MaxInst{..} sol = partialMinMax corLits cnf sol allMaxTerms True
partialGrade' :: OutputMonad m => MaxInst -> Cnf -> LangM m
partialGrade' MaxInst{..} sol = partialMinMax corLits cnf sol allMaxTerms True
where
corLits = atomics cnf
allMaxTerms = not $ all (\c -> amount c == length corLits) $ getClauses sol
Expand Down Expand Up @@ -202,7 +204,8 @@ completeMinMax showSolution correct solution =
solTable = getTable solution
(_,diff) = pairwiseCheck (zip3 (readEntries solTable) (readEntries $ getTable correct) [1..])

completeGrade :: OutputMonad m => MaxInst -> Delayed Cnf -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser


completeGrade :: OutputMonad m => MaxInst -> Cnf -> LangM m
completeGrade MaxInst{..} = completeMinMax showSolution cnf
completeGrade' :: OutputMonad m => MaxInst -> Cnf -> LangM m
completeGrade' MaxInst{..} = completeMinMax showSolution cnf
16 changes: 10 additions & 6 deletions src/LogicTasks/Semantics/Min.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import Formula.Types (Dnf, Literal(..), amount, atomics, genDnf, getConjunctions
import Formula.Util (mkCon, mkDnf, hasEmptyCon, isEmptyDnf)
import LogicTasks.Helpers (extra, formulaKey)
import Util (tryGen, withRatio)

import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))



Expand Down Expand Up @@ -85,15 +86,18 @@ verifyQuiz = Max.verifyQuiz
start :: Dnf
start = mkDnf [mkCon [Literal 'A']]

partialGrade :: OutputMonad m => MinInst -> Delayed Dnf -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser


partialGrade :: OutputMonad m => MinInst -> Dnf -> LangM m
partialGrade MinInst{..} sol = Max.partialMinMax corLits dnf sol allMinTerms False
partialGrade' :: OutputMonad m => MinInst -> Dnf -> LangM m
partialGrade' MinInst{..} sol = Max.partialMinMax corLits dnf sol allMinTerms False
where
corLits = atomics dnf
allMinTerms = not $ all (\c -> amount c == length corLits) $ getConjunctions sol


completeGrade :: OutputMonad m => MinInst -> Delayed Dnf -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser

completeGrade :: OutputMonad m => MinInst -> Dnf -> LangM m
completeGrade MinInst{..} = Max.completeMinMax showSolution dnf
completeGrade' :: OutputMonad m => MinInst -> Dnf -> LangM m
completeGrade' MinInst{..} = Max.completeMinMax showSolution dnf
6 changes: 0 additions & 6 deletions src/LogicTasks/Semantics/Pick.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import Data.Maybe (fromJust)
import Data.List (nubBy)




genPickInst :: PickConfig -> Gen PickInst
genPickInst PickConfig{ cnfConf = CnfConfig {baseConf = BaseConfig{..}, ..}, ..} = do
cnfs <- tryGen (vectorOf amountOfOptions (getCnf usedLiterals)) 100 ((amountOfOptions ==) . length . nubBy isSemanticEqual)
Expand Down Expand Up @@ -108,17 +106,13 @@ verifyQuiz PickConfig{..}
start :: Number
start = Number Nothing



partialGrade :: OutputMonad m => PickInst -> Number -> LangM m
partialGrade _ (Number Nothing) = refuse $ indent $
translate $ do
german "Es wurde kein Index angegeben."
english "You did not give an index."

partialGrade _ _ = pure ()


completeGrade :: OutputMonad m => PickInst -> Number -> LangM m
completeGrade PickInst{..} (Number index) =
if fromJust index == correct
Expand Down
17 changes: 10 additions & 7 deletions src/LogicTasks/Semantics/Prolog.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import Util(prevent, preventWithHint)
import Control.Monad (when)
import LogicTasks.Helpers (example, extra)
import Formula.Helpers (hasTheClauseShape)

import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))

genPrologInst :: PrologConfig -> Gen PrologInst
genPrologInst PrologConfig{..} = (do
Expand Down Expand Up @@ -130,10 +131,11 @@ verifyQuiz PrologConfig{..}
start :: (PrologLiteral, PrologClause)
start = (PrologLiteral True "a" ["x"], mkPrologClause [])

partialGrade :: OutputMonad m => PrologInst -> Delayed (PrologLiteral, PrologClause) -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser


partialGrade :: OutputMonad m => PrologInst -> (PrologLiteral, PrologClause) -> LangM m
partialGrade PrologInst{..} sol = do
partialGrade' :: OutputMonad m => PrologInst -> (PrologLiteral, PrologClause) -> LangM m
partialGrade' PrologInst{..} sol = do
prevent (not (fst sol `member` availLits)) $
translate $ do
german "Gewähltes Literal kommt in den Klauseln vor?"
Expand All @@ -157,10 +159,11 @@ partialGrade PrologInst{..} sol = do
solLits = pLiterals $ snd sol
extraLiterals = toList $ solLits `difference` availLits

completeGrade :: OutputMonad m => PrologInst -> Delayed (PrologLiteral, PrologClause) -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser


completeGrade :: OutputMonad m => PrologInst -> (PrologLiteral, PrologClause) -> LangM m
completeGrade PrologInst{..} sol =
completeGrade' :: OutputMonad m => PrologInst -> (PrologLiteral, PrologClause) -> LangM m
completeGrade' PrologInst{..} sol =
case resolveResult of
Nothing -> refuse $ indent $ do
translate $ do
Expand Down
16 changes: 11 additions & 5 deletions src/LogicTasks/Semantics/Resolve.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import Control.Monad (unless, when)
import Control.Applicative (Alternative)
import Data.Foldable.Extra (notNull)
import Text.PrettyPrint.Leijen.Text (Pretty(pretty))

import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))



Expand Down Expand Up @@ -197,9 +198,11 @@ gradeSteps steps appliedIsNothing = do
fromJust (resolve c1 c2 x) /= r) (resolvableWith c1 c2)) steps
checkEmptyClause = null steps || not (isEmptyClause $ third3 $ last steps)

partialGrade :: OutputMonad m => ResolutionInst -> Delayed [ResStep] -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser

partialGrade :: OutputMonad m => ResolutionInst -> [ResStep] -> LangM m
partialGrade ResolutionInst{..} sol = do
partialGrade' :: OutputMonad m => ResolutionInst -> [ResStep] -> LangM m
partialGrade' ResolutionInst{..} sol = do
checkMapping

preventWithHint (not $ null wrongLitsSteps)
Expand Down Expand Up @@ -228,8 +231,11 @@ partialGrade ResolutionInst{..} sol = do
applied = applySteps clauses steps
stepsGraded = gradeSteps steps (isNothing applied)

completeGrade :: (OutputMonad m, Alternative m) => ResolutionInst -> [ResStep] -> LangM m
completeGrade ResolutionInst{..} sol = (if isCorrect then id else refuse) $ do
completeGrade :: (OutputMonad m, Alternative m) => ResolutionInst -> Delayed [ResStep] -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser

completeGrade' :: (OutputMonad m, Alternative m) => ResolutionInst -> [ResStep] -> LangM m
completeGrade' ResolutionInst{..} sol = (if isCorrect then id else refuse) $ do
unless printFeedbackImmediately $ do
recoverFrom stepsGraded

Expand Down
17 changes: 10 additions & 7 deletions src/LogicTasks/Semantics/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import Formula.Resolution (resolvable, resolve)
import LogicTasks.Helpers (clauseKey, example, extra)
import Util (checkBaseConf, prevent, preventWithHint, tryGen)
import Control.Monad (when)


import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))


genStepInst :: StepConfig -> Gen StepInst
Expand Down Expand Up @@ -92,10 +92,11 @@ verifyQuiz StepConfig{..} = checkBaseConf baseConf
start :: StepAnswer
start = StepAnswer Nothing

partialGrade :: OutputMonad m => StepInst -> Delayed StepAnswer -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser


partialGrade :: OutputMonad m => StepInst -> StepAnswer -> LangM m
partialGrade StepInst{..} sol = do
partialGrade' :: OutputMonad m => StepInst -> StepAnswer -> LangM m
partialGrade' StepInst{..} sol = do

prevent (isNothing $ step sol) $
translate $ do
Expand Down Expand Up @@ -126,10 +127,12 @@ partialGrade StepInst{..} sol = do
solLits = fromList $ literals $ snd mSol
extraLiterals = toList (solLits `difference` availLits)

completeGrade :: OutputMonad m => StepInst -> Delayed StepAnswer -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser


completeGrade :: OutputMonad m => StepInst -> StepAnswer -> LangM m
completeGrade StepInst{..} sol =
completeGrade' :: OutputMonad m => StepInst -> StepAnswer -> LangM m
completeGrade' StepInst{..} sol =
case resolve clause1 clause2 (fst mSol) of
Nothing -> refuse $ indent $ do
translate $ do
Expand Down
16 changes: 11 additions & 5 deletions src/LogicTasks/Syntax/SimplestFormula.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import Tasks.SuperfluousBrackets.Config (
import Trees.Helpers
import Trees.Types
import Control.Monad (when)
import Formula.Parsing.Delayed (Delayed, withDelayed)
import Formula.Parsing (Parse(..))
import Trees.Parsing()



Expand Down Expand Up @@ -74,9 +77,11 @@ start :: FormulaAnswer
start = FormulaAnswer Nothing


partialGrade :: OutputMonad m => SuperfluousBracketsInst -> Delayed FormulaAnswer -> LangM m
partialGrade inst = partialGrade' inst `withDelayed` parser

partialGrade :: OutputMonad m => SuperfluousBracketsInst -> FormulaAnswer -> LangM m
partialGrade SuperfluousBracketsInst{..} f
partialGrade' :: OutputMonad m => SuperfluousBracketsInst -> FormulaAnswer -> LangM m
partialGrade' SuperfluousBracketsInst{..} f
| isNothing $ maybeForm f =
reject $ do
english "Your submission is empty."
Expand Down Expand Up @@ -110,10 +115,11 @@ partialGrade SuperfluousBracketsInst{..} f
correctLits = sort $ nub $ collectLeaves tree
correctOpsNum = numOfOps tree

completeGrade :: OutputMonad m => SuperfluousBracketsInst -> Delayed FormulaAnswer -> LangM m
completeGrade inst = completeGrade' inst `withDelayed` parser


completeGrade :: OutputMonad m => SuperfluousBracketsInst -> FormulaAnswer -> LangM m
completeGrade inst sol
completeGrade' :: OutputMonad m => SuperfluousBracketsInst -> FormulaAnswer -> LangM m
completeGrade' inst sol
| show (fromJust (maybeForm sol)) /= simplestString inst = refuse $ do
instruct $ do
english "Your solution is incorrect."
Expand Down
Loading
Loading