Skip to content
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
61 changes: 61 additions & 0 deletions kore/src/ErrorContext.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{- |
Copyright : (c) Runtime Verification, 2020
License : NCSA

-}

module ErrorContext
( ErrorContext (..)
, withErrorContext
) where

import Prelude

import Control.Exception
( Exception (..)
, SomeException
, mapException
)
import Data.String
( fromString
)
import Data.Typeable
( Typeable
)

import Pretty
( Pretty
)
import qualified Pretty

data ErrorContext where
ErrorContext
:: (Pretty context, Show context)
=> String -- ^ A brief message (one line) introducing the context.
-> context -- ^ Some 'Pretty'-printable data for context.
-> SomeException -- ^ The error itself.
-> ErrorContext
deriving (Typeable)

deriving instance Show ErrorContext

instance Pretty ErrorContext where
pretty (ErrorContext intro context someException) =
Pretty.vsep
[ fromString intro
, Pretty.indent 4 (Pretty.pretty context)
, Pretty.prettyException someException
]

instance Exception ErrorContext where
displayException = show . Pretty.pretty

{- | Compute a value, putting error messages in context.
-}
withErrorContext
:: (Pretty context, Show context)
=> String
-> context
-> a -- ^ The value computed.
-> a
withErrorContext intro context = mapException (ErrorContext intro context)
11 changes: 8 additions & 3 deletions kore/src/Kore/Internal/Condition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Kore.Internal.Condition

import Prelude.Kore

import ErrorContext
import Kore.Attribute.Pattern.FreeVariables
( freeVariables
, isFreeVariable
Expand Down Expand Up @@ -182,11 +183,15 @@ The 'normalized' part becomes the normalized 'substitution', while the

-}
fromNormalizationSimplified
:: InternalVariable variable
:: HasCallStack
=> InternalVariable variable
=> Normalization variable
-> Condition variable
fromNormalizationSimplified Normalization { normalized, denormalized } =
fromNormalizationSimplified
normalization@Normalization { normalized, denormalized }
=
predicate' <> substitution'
& withErrorContext "while normalizing substitution" normalization
where
predicate' =
Conditional.fromPredicate
Expand All @@ -195,7 +200,7 @@ fromNormalizationSimplified Normalization { normalized, denormalized } =
$ Substitution.wrap denormalized
substitution' =
Conditional.fromSubstitution
$ Substitution.unsafeWrap (Substitution.assignmentToPair <$> normalized)
$ Substitution.unsafeWrapFromAssignments normalized
markSimplifiedIfChildrenSimplified childrenList result =
Predicate.setSimplified childrenSimplified result
where
Expand Down
40 changes: 37 additions & 3 deletions kore/src/Kore/Internal/Substitution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import qualified Data.Set as Set
import qualified Generics.SOP as SOP
import qualified GHC.Generics as GHC

import ErrorContext
import Kore.Attribute.Pattern.FreeVariables as FreeVariables
import qualified Kore.Attribute.Pattern.Simplified as Attribute
( Simplified (..)
Expand All @@ -92,7 +93,12 @@ import Kore.TopBottom
( TopBottom (..)
)
import Kore.Unparser
( unparseToString
( Unparse
, unparse
, unparseToString
)
import Pretty
( Pretty
)
import qualified Pretty
import qualified SQL
Expand All @@ -118,6 +124,14 @@ instance NFData variable => NFData (Assignment variable)

instance Hashable variable => Hashable (Assignment variable)

instance (Ord variable, Unparse variable) => Pretty (Assignment variable) where
pretty Assignment_ { assignedVariable, assignedTerm } =
Pretty.vsep
[ Pretty.hsep ["assigned variable:", unparse assignedVariable]
, "assigned term:"
, Pretty.indent 4 (unparse assignedTerm)
]

-- | Smart constructor for 'Assignment'. It enforces the invariant
-- that for variable renaming, the smaller variable will be on the
-- left of the substitution.
Expand Down Expand Up @@ -419,7 +433,7 @@ wrap xs = Substitution xs
-- this unless you are sure you need it.
unsafeWrap
:: HasCallStack
=> Ord variable
=> InternalVariable variable
=> [(SomeVariable variable, TermLike variable)]
Copy link
Contributor

@andreiburdusa andreiburdusa Jul 28, 2020

Choose a reason for hiding this comment

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

I see Ana left a "TODO" comment on line 431 about a posible refactoring. I could take care of it. What do you think @ana-pantilie @ttuegel ?
(I'm not able to comment on that line)

Copy link
Contributor

@ana-pantilie ana-pantilie Jul 28, 2020

Choose a reason for hiding this comment

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

We already have unsafeWrapFromAssignments, and it looks like the major difference between these two is that unsafeWrap doesn't enforce the variable renaming invariant. I believe the question here is if we want to be able to create a Substitution like this, even for testing (where unsafeWrap is most widely used). @ttuegel what do you think? Is there any reason to keep unsafeWrap the way it is?

-> Substitution variable
unsafeWrap =
Expand All @@ -436,15 +450,18 @@ unsafeWrap =
& assert (not $ any depends $ Map.keys subst)
-- and if this is an element variable substitution, the substitution
-- must be defined.
-- TODO (thomas.tuegel): isBottom -> isDefinedPattern
& assert (not $ isElementVariable var && isBottom termLike)
& withErrorContext "while wrapping substitution" (assign var termLike)
where
Variable { variableName } = var
occurs = TermLike.hasFreeVariable variableName
depends Variable { variableName = variableName' } =
TermLike.hasFreeVariable variableName' termLike

unsafeWrapFromAssignments
:: Ord variable
:: HasCallStack
=> InternalVariable variable
=> [Assignment variable]
-> Substitution variable
unsafeWrapFromAssignments =
Expand Down Expand Up @@ -678,6 +695,23 @@ instance Semigroup (Normalization variable) where
instance Monoid (Normalization variable) where
mempty = Normalization mempty mempty

instance InternalVariable variable => Pretty (Normalization variable) where
pretty Normalization { normalized, denormalized } =
Pretty.vsep
[ "normalized:"
, (Pretty.indent 4 . Pretty.vsep) (map prettyPair normalized)
, "denormalized:"
, (Pretty.indent 4 . Pretty.vsep) (map prettyPair denormalized)
]
where
prettyPair assignment =
Pretty.vsep
[ "variable:"
, Pretty.indent 4 (unparse $ assignedVariable assignment)
, "term:"
, Pretty.indent 4 (unparse $ assignedTerm assignment)
]

mkNormalization
:: InternalVariable variable
=> [(SomeVariable variable, TermLike variable)]
Expand Down
13 changes: 13 additions & 0 deletions kore/src/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ module Pretty
, renderString
, renderIO
, hPutDoc, putDoc
, prettyException
) where

import Prelude.Kore

import Control.Exception
( Exception
, displayException
)
import Data.String
( fromString
)
import Data.Text
( Text
)
Expand Down Expand Up @@ -52,3 +60,8 @@ flattenSimpleDocStream = worker

renderText :: SimpleDocStream ann -> Text
renderText = renderStrict

{- | Display an 'Exception' nicely for the user.
-}
prettyException :: Exception exn => exn -> Doc ann
prettyException = vsep . map fromString . lines . displayException