da una derivacion dice si es válida o no. Esto es
--   solo para las derivaciones por recursión. Si luego se implementa
--   otro tipo de derivación, entonces debería diferenciarse.
checkDer :: [Operator] -> Declarations -> Declarations ->
           [ThmDecl] -> Derivation -> EDeriv' (Annot FunDecl)
checkDer pops decls imDecls thms der = do
               
                let (declS,mDeclF,declD) = (spec der,prog der,deriv der) 
                -- primero chequeamos que la variable sobre la que se hace
                -- la derivación por recursión es la misma que está definida en
                -- la especificación.
                    v = declD ^. derVar
                    f = declD ^. derFun
                    pfsnt = declD ^. derCases
                    vname = tRepr v
                    spVars = L.map tRepr $ declS ^. specArgs
                    expr = declS ^. specSpec
                    (Just texpr) = getType expr
                    rel = getRelationFromType texpr
                whenDer (vname `elem` spVars) ([InvalidVariable  v],declD)
                -- Remplazamos la variable por la de la especificación, ya que ésta está
                -- tipada.
                vspec <- getVarInSpec v declS declD
                let declD' = Deriv f vspec pfsnt
                -- Ahora construimos una prueba inductiva con los datos de la derivación.
                -- Se asume que la declaración está bien tipada
                    fexpr = firstExpr declS
                    caseExpr = caseExprFromDerivation vspec declD'
                --  agregar como hipotesis la especificacion
                    hypSpec = mkIndHyp f rel fexpr expr
                    pfs' = addHypInSubProofs hypSpec pfsnt
                    ctx = addHypothesis' hypSpec M.empty
                    prf' = Ind ctx rel (PE.toFocus fexpr) 
                                       (PE.toFocus caseExpr) 
                                       (PE.toFocus $ PE.Var vspec) 
                                       pfs'
                     -- Agregamos todas las declaraciones como hipotesis                                       
                    prf = addDeclHypothesis decls thms imDecls prf'
                    valPrf = validateProof pops prf
                    funPos = derivPos der
                    derivedFun = createFunDecl declS vspec declD'
                _ <- maybe (return ()) (isDeclared declD' derivedFun) mDeclF
                
                case valPrf of
                     Left err -> Left ([ProofNotValid err],declD')
                     Right _ -> return (funPos,derivedFun)
                                
checkDer :: [Operator] -> Declarations -> Declarations ->
           [ThmDecl] -> Derivation -> EDeriv' (Annot FunDecl)
checkDer pops decls imDecls thms der = do
               
                let (declS,mDeclF,declD) = (spec der,prog der,deriv der) 
                -- primero chequeamos que la variable sobre la que se hace
                -- la derivación por recursión es la misma que está definida en
                -- la especificación.
                    v = declD ^. derVar
                    f = declD ^. derFun
                    pfsnt = declD ^. derCases
                    vname = tRepr v
                    spVars = L.map tRepr $ declS ^. specArgs
                    expr = declS ^. specSpec
                    (Just texpr) = getType expr
                    rel = getRelationFromType texpr
                whenDer (vname `elem` spVars) ([InvalidVariable  v],declD)
                -- Remplazamos la variable por la de la especificación, ya que ésta está
                -- tipada.
                vspec <- getVarInSpec v declS declD
                let declD' = Deriv f vspec pfsnt
                -- Ahora construimos una prueba inductiva con los datos de la derivación.
                -- Se asume que la declaración está bien tipada
                    fexpr = firstExpr declS
                    caseExpr = caseExprFromDerivation vspec declD'
                --  agregar como hipotesis la especificacion
                    hypSpec = mkIndHyp f rel fexpr expr
                    pfs' = addHypInSubProofs hypSpec pfsnt
                    ctx = addHypothesis' hypSpec M.empty
                    prf' = Ind ctx rel (PE.toFocus fexpr) 
                                       (PE.toFocus caseExpr) 
                                       (PE.toFocus $ PE.Var vspec) 
                                       pfs'
                     -- Agregamos todas las declaraciones como hipotesis                                       
                    prf = addDeclHypothesis decls thms imDecls prf'
                    valPrf = validateProof pops prf
                    funPos = derivPos der
                    derivedFun = createFunDecl declS vspec declD'
                _ <- maybe (return ()) (isDeclared declD' derivedFun) mDeclF
                
                case valPrf of
                     Left err -> Left ([ProofNotValid err],declD')
                     Right _ -> return (funPos,derivedFun)
checkDer pops decls imDecls thms der = do
               
                let (declS,mDeclF,declD) = (spec der,prog der,deriv der) 
                -- primero chequeamos que la variable sobre la que se hace
                -- la derivación por recursión es la misma que está definida en
                -- la especificación.
                    v = declD ^. derVar
                    f = declD ^. derFun
                    pfsnt = declD ^. derCases
                    vname = tRepr v
                    spVars = L.map tRepr $ declS ^. specArgs
                    expr = declS ^. specSpec
                    (Just texpr) = getType expr
                    rel = getRelationFromType texpr
                whenDer (vname `elem` spVars) ([InvalidVariable  v],declD)
                -- Remplazamos la variable por la de la especificación, ya que ésta está
                -- tipada.
                vspec <- getVarInSpec v declS declD
                let declD' = Deriv f vspec pfsnt
                -- Ahora construimos una prueba inductiva con los datos de la derivación.
                -- Se asume que la declaración está bien tipada
                    fexpr = firstExpr declS
                    caseExpr = caseExprFromDerivation vspec declD'
                --  agregar como hipotesis la especificacion
                    hypSpec = mkIndHyp f rel fexpr expr
                    pfs' = addHypInSubProofs hypSpec pfsnt
                    ctx = addHypothesis' hypSpec M.empty
                    prf' = Ind ctx rel (PE.toFocus fexpr) 
                                       (PE.toFocus caseExpr) 
                                       (PE.toFocus $ PE.Var vspec) 
                                       pfs'
                     -- Agregamos todas las declaraciones como hipotesis                                       
                    prf = addDeclHypothesis decls thms imDecls prf'
                    valPrf = validateProof pops prf
                    funPos = derivPos der
                    derivedFun = createFunDecl declS vspec declD'
                _ <- maybe (return ()) (isDeclared declD' derivedFun) mDeclF
                
                case valPrf of
                     Left err -> Left ([ProofNotValid err],declD')
                     Right _ -> return (funPos,derivedFun)