@@ -7,6 +7,7 @@ import RelationalError
77import qualified Data.Map as M
88import qualified Data.HashSet as HS
99import Control.Monad.State hiding (join)
10+import Data.Maybe
1011
1112--relvar state is needed in evaluation of relational expression but only as read-only in order to extract current relvar values
1213evalRelationalExpr :: RelationalExpr -> DatabaseState (Either RelationalError Relation)
@@ -144,8 +145,12 @@ setRelVar :: String -> Relation -> DatabaseState (Maybe RelationalError)
144145setRelVar relVarName rel = do
145146 state <- get
146147 let newRelVars = M.insert relVarName rel $ relationVariables state
147− put $ DatabaseContext (inclusionDependencies state) newRelVars
148− return Nothing
148+ case checkConstraints state of
149+ Just err -> return $ Just err
150+ Nothing -> do
151+ put $ DatabaseContext (inclusionDependencies state) newRelVars
152+ return Nothing
153+
149154
150155evalContextExpr :: DatabaseExpr -> DatabaseState (Maybe RelationalError)
151156evalContextExpr (Define relVarName attrs) = do
@@ -181,7 +186,11 @@ evalContextExpr (Delete relVarName) = do
181186
182187evalContextExpr (Update relVarName attrAssignments) = undefined
183188
184−evalContextExpr (AddInclusionDependency dep) = undefined
189+evalContextExpr (AddInclusionDependency dep) = do
190+ state <- get
191+ let newDeps = HS.insert dep (inclusionDependencies state)
192+ put $ DatabaseContext newDeps (relationVariables state)
193+ return Nothing
185194
186195evalContextExpr (MultipleExpr exprs) = do
187196 evald <- mapM evalContextExpr exprs
@@ -190,5 +199,37 @@ evalContextExpr (MultipleExpr exprs) = do
190199-- restrict relvar to get affected tuples, update tuples, delete restriction from relvar, relvar = relvar union updated tuples
191200--evalRelVarExpr (Update relVarName updateMap) = do
192201
202+--run verification on all constraints
203+checkConstraints :: DatabaseContext -> Maybe RelationalError
204+checkConstraints context = case failures of
205+ [] -> Nothing
206+ l:ls -> Just l
207+ where
208+ failures = catMaybes $ map checkIncDep (HS.toList deps)
209+ deps = inclusionDependencies context
210+ eval expr = runState (evalRelationalExpr expr) context
211+ checkIncDep (InclusionDependency depName subsetExpr supersetExpr) = case evaldSub of
212+ Left err -> Just err
213+ Right relSub -> case evaldSub of
214+ Left err -> Just err
215+ Right relSuper -> case union relSub relSuper of
216+ Left err -> Just err
217+ Right resultRel -> case resultRel of
218+ False -> Just $ InclusionDependencyCheckError depName
219+ True -> Nothing
220+ where
221+ evaldSub = eval subsetExpr
222+ evaldSuper = eval supersetExpr
223+
224+checkConstraint :: InclusionDependency -> DatabaseState (Maybe RelationalError)
225+checkConstraint (InclusionDependency name subDep superDep) = do
226+ evalSub <- evalRelExpr subDep
227+ evalSuper <- evalRelExpr superDep
228+ result <- liftM2 union evalSub evalSuper
229+
230+
231+
232+
233+
193234
194235