-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathPick.hs
More file actions
180 lines (146 loc) · 6.46 KB
/
Pick.hs
File metadata and controls
180 lines (146 loc) · 6.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE FlexibleContexts #-}
{-# language RecordWildCards #-}
{-# LANGUAGE NamedFieldPuns #-}
module LogicTasks.Semantics.Pick where
import Control.Monad (when)
import Control.OutputCapable.Blocks (
GenericOutputCapable (..),
LangM,
OutputCapable,
english,
german,
translate,
singleChoiceSyntax,
singleChoice,
ArticleToUse (DefiniteArticle),
translations,
)
import Test.QuickCheck (Gen, suchThat, elements)
import Config (Number(..), PickConfig(..), PickInst(..), FormulaConfig (..), FormulaInst (..), BaseConfig (..), NormalFormConfig(..))
import Formula.Util (isSemanticEqual)
import Formula.Types (availableLetter, getTable, Formula (atomics))
import Formula.Printing (showIndexedList)
import LogicTasks.Helpers (extra)
import Data.Maybe (fromJust)
import Trees.Generate (genSynTree)
import Tasks.SynTree.Config (SynTreeConfig (..))
import Util (withRatio, vectorOfUniqueBy, checkTruthValueRangeAndFormulaConf, formulaDependsOnAllAtoms)
import LogicTasks.Util (genCnf', genDnf', displayFormula, usesAllAtoms, isEmptyFormula)
genPickInst :: PickConfig -> Gen PickInst
genPickInst PickConfig{..} = do
formulas <- vectorOfUniqueBy
amountOfOptions
isSemanticEqual
$ flip suchThat formulaDependsOnAllAtoms $ case formulaConfig of
(FormulaArbitrary syntaxTreeConfig) ->
InstArbitrary <$> genSynTree syntaxTreeConfig `suchThat` withRatio percentTrueEntries
(FormulaCnf cnfCfg) ->
InstCnf <$> genCnf' cnfCfg `suchThat` withRatio percentTrueEntries
(FormulaDnf dnfCfg) ->
InstDnf <$> genDnf' dnfCfg `suchThat` withRatio percentTrueEntries
correct <- elements [1..amountOfOptions]
pure $ PickInst {
formulas,
correct,
showSolution = printSolution,
addText = extraText
}
description :: OutputCapable m => Bool -> PickInst -> LangM m
description inputHelp PickInst{..} = do
paragraph $ do
translate $ do
german "Betrachten Sie die folgende Formel:"
english "Consider the following formula:"
indent $ code $ availableLetter (atomics correctFormula) : " = " ++ displayFormula correctFormula
pure ()
paragraph $ do
translate $ do
german "Welche der folgenden Wahrheitstafeln passt zu der Formel? Geben Sie die richtige Tafel durch ihre Nummer an."
english "Which of the following truth tables represents the formula? Specify the correct table by giving its number."
indent $ code $ showIndexedList 120 5 $ map getTable formulas
pure ()
when inputHelp $ paragraph $ indent $ do
translate $ do
german "Ein Lösungsversuch könnte so aussehen: "
english "A solution attempt could look like this: "
code "1"
pure ()
extra addText
pure ()
where
correctFormula = formulas !! (correct - 1)
verifyStatic :: OutputCapable m => PickInst -> LangM m
verifyStatic PickInst{..}
| null formulas =
refuse $ indent $ translate $ do
german "Die Liste der Formeln ist leer."
english "The list of formulas is empty."
| any isEmptyFormula formulas =
refuse $ indent $ translate $ do
german "Mindestens eine der Formeln ist für diese Aufgabe nicht geeignet."
english "At least one given formula is not suitable for this task."
| length formulas < correct || correct <= 0 =
refuse $ indent $ translate $ do
german "Der angegebene Index existiert nicht."
english "The given index does not exist."
| otherwise = pure()
verifyQuiz :: OutputCapable m => PickConfig -> LangM m
verifyQuiz PickConfig{..}
| tooFewAtoms formulaConfig =
refuse $ indent $ translate $ do
german "Es müssen mindestens drei Atome zur Verfügung stehen."
english "At least three atoms need to be available."
| amountOfOptions < 2 =
refuse $ indent $ translate $ do
german "Es muss mindestens zwei Optionen geben."
english "At least two options need to be given."
| not $ hasMinUniqueAtoms 2 formulaConfig =
refuse $ indent $ translate $ do
german "Es muss mindestens zwei unterschiedliche Atome geben."
english "At least two unique atoms are required."
| doesOvershootOptions formulaConfig =
refuse $ indent $ translate $ do
german "Die Anzahl Optionen übersteigt die Anzahl möglicher, unterschiedlicher Formeln."
english "The amount of options is higher than the amount of possible, distinct formulas."
| not $ usesAllAtoms formulaConfig =
refuse $ indent $ translate $ do
german "Bei dieser Aufgabe müssen alle verfügbaren Atome verwendet werden."
english "All available atoms must be used for this task."
| rangeH - rangeL < 30 =
refuse $ indent $ translate $ do
german "Die Beschränkung der Wahr-Einträge sollte eine Reichweite von 30 nicht unterschreiten."
english "The given restriction on True entries should not fall below a range of 30."
| otherwise = checkTruthValueRangeAndFormulaConf percentTrueEntries formulaConfig
where
(rangeL, rangeH) = percentTrueEntries
hasMinUniqueAtoms x (FormulaArbitrary syntaxTreeConfig) = minAmountOfUniqueAtoms syntaxTreeConfig >= x
hasMinUniqueAtoms _ _ = True
doesOvershootOptions (FormulaArbitrary syntaxTreeConfig)
= amountOfOptions > 4*2^ length (availableAtoms syntaxTreeConfig)
doesOvershootOptions (FormulaCnf cnfCfg)
= amountOfOptions > 4*2^ length (usedAtoms (baseConf cnfCfg))
doesOvershootOptions (FormulaDnf dnfCfg)
= amountOfOptions > 4*2^ length (usedAtoms (baseConf dnfCfg))
tooFewAtoms (FormulaArbitrary syntaxTreeConfig) = length (availableAtoms syntaxTreeConfig) < 3
tooFewAtoms _ = False
start :: Number
start = Number Nothing
partialGrade :: OutputCapable 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 PickInst{formulas} (Number (Just index)) = singleChoiceSyntax True [1..length formulas] index
completeGrade :: OutputCapable m => PickInst -> Number -> LangM m
completeGrade PickInst{..} (Number index) = singleChoice
what
displaySolution
correct
(fromJust index)
where
what = translations $ do
german "Index"
english "index"
displaySolution | showSolution = Just (DefiniteArticle, show correct)
| otherwise = Nothing