tamarin-prover-0.6.0.0: src/Theory/Tools/UniqueFactInstances.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
-- Copyright : (c) 2012 Simon Meier
-- License : GPL v3 (see LICENSE)
--
-- Maintainer : Simon Meier <iridcode@gmail.com>
-- Portability : portable
--
-- Computate an under-approximation to the set of all facts with unique
-- instances, i.e., fact whose instances never occur more than once in a
-- state. We use this information to reason about protocols that exploit
-- exclusivity of linear facts.
module Theory.Tools.UniqueFactInstances (
-- * Computing unique fact instances.
simpleUniqueFactInstances
) where
import Extension.Prelude (sortednub)
import Control.Applicative
import Control.Monad.Fresh
import Data.Label
import qualified Data.Set as S
import Theory.Model
-- | Compute a simple under-approximation to the set of facts with uniqe
-- instances. A fact-tag is guaranteed to have uniqe instances, if it never
-- occurs twice in the conclusions of a rule and each of its occurrences in
-- the conclusion of a rule is guarded by an equal premise or a Fr-fact
-- generating one of the terms used in the fact that we are analyzing.
--
-- We exclude facts that are not copied in a rule, as they are already handled
-- properly by the naive backwards reasoning.
simpleUniqueFactInstances :: [ProtoRuleE] -> S.Set FactTag
simpleUniqueFactInstances rules = S.fromList $ do
tag <- candidates
guard (all (guardedSingletonCopy tag) rules)
return tag
where
candidates = sortednub $ do
ru <- rules
filter (`elem` (factTag <$> get rPrems ru)) (factTag <$> get rConcs ru)
guardedSingletonCopy tag ru = and $ do
copy <- filter ((tag ==) . factTag) (get rConcs ru)
return $
(length copies <= 1)
&& ( (copy `elem` get rPrems ru)
|| any (\t -> freshFact t `elem` get rPrems ru) (factTerms copy)
)
where
copies = filter ((tag ==) . factTag) (get rConcs ru)