{- Copyright (C) 2010-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -} {- | [@AUTHOR@] Dr. Alistair Ward [@DESCRIPTION@] * Defines those options relating to the "RegExDot.RegEx"-runtime. * These tend to be options which don't affect the result, only the means by which it is achieved. * Whilst similar structures are present in other regex-implementations, there's no standardisation of the fields. -} module RegExDot.ExecutionOptions( -- * Types -- ** Data-types ExecutionOptions(..), -- * Functions -- ** Mutators setVerbose ) where import qualified Data.Default import qualified ToolShed.Options -- | The switches used to control execution of the /regex/-engine. data ExecutionOptions = MkExecutionOptions { abortTrialRepetitionsOnInherentFailure :: Bool, -- ^ If an /alternative/ can't match, irrespective of the subsequent /RegExDot.RegEx.Concatenation/, then avoid futile trial /RegExDot.Repeatable.Repetitions/. The converse of 'checkForUnconsumableData'. abortTrialRepetitionsOnZeroConsumption :: Bool, -- ^ Check for zero data-consumption by the @n@-th /RegExDot.Repeatable.Repeatable RegExDot.RegEx.CaptureGroup/, before attempting @n+1@. bypassInputDataForLiberalConsumer :: Bool, -- ^ Whether to bypass reading of the input data, if the mapping to specific /RegExDot.RegEx.RepeatablePattern/s isn't required, & the /RegExDot.RegEx.ExtendedRegEx/ can consume the required quantity of anything. catchIncompatibleAnchors :: Bool, -- ^ Avoid futile trial solutions, involving repetitions of anchored alternatives, which must consume data. checkExistenceOfInelasticTail :: Bool, -- ^ If the /RegExDot.RegEx.ExtendedRegEx/ ends in an inelastic (zero /Star-height/) tail, confirm its existence at the end of the /RegExDot.RegEx.InputData/. checkForUnconsumableData :: Bool, -- ^ Check whether there's no possibility of consuming some of the input data. The converse of 'abortTrialRepetitionsOnInherentFailure'. moderateGreed :: Bool, -- ^ Greedily consume data, only up to the limit beyond which, future requirements would be compromised. permitReorderingOfAlternatives :: Bool, -- ^ Permit /RegExDot.RegEx.Alternatives/ to be re-ordered, in an attempt to more quickly locate a result. preferAlternativesWhichFeedTheGreedy :: Bool, -- ^ Within the /RegExDot.RegEx.MatchedData/ from which each candidate /RegExDot.RegEx.Match/ amongst sequences of /RegExDot.RegEx.Alternatives/, is ultimately composed, prefer /RegExDot.ConsumptionBounds.ConsumptionBounds/ of /RegExDot.RegEx.InputData/, beyond /RegExDot.Repeatable.getFewest/, by /RegExDot.Repeatable.isGreedy RegExDot.RegEx.RepeatablePattern/s. preferAlternativesWhichMimickUnrolling :: Bool, -- ^ Compare /RegExDot.ConsumptionBounds.ConsumptionBounds/ on successive /RegExDot.Repeatable.Repetitions/ of /RegExDot.RegEx.CaptureGroup/, between candidate /RegExDot.RegEx.Match/es, to mimic the behaviour of the unrolled /RegExDot.Repeatable.Repetitions/. preferFewerRepeatedAlternatives :: Bool, -- ^ Prefer fewer /RegExDot.Repeatable.Repetitions/ of /RegExDot.RegEx.Alternatives/, to discourage the capture of null lists of /RegExDot.RegEx.InputData/. requireMatchList :: Bool, -- ^ If merely interested in a 'Bool' result, rather than the optimal mapping of input data to /RegExDot.RegEx.RepeatablePattern/s, avoid unnecessary evaluation of the /RegEx.Match/. unrollRepeatedSingletonAlternative :: Bool, -- ^ Check whether /RegExDot.RegEx.Alternatives/ consists of just a singleton /RegExDot.RegEx.ExtendedRegEx/, & has therefore been used merely as a capture-group. Though this doesn't affect the result, it vastly improves efficiency. useFirstMatchAmongAlternatives :: Bool, -- ^ Rather than performing an exhaustive search for the optimal choice amongst /RegExDot.RegEx.Alternatives/, merely select the first that matches; conform to /Perl/ rather than /POSIX/. validateMinConsumptionOfAlternatives :: Bool -- ^ When the number of repetitions of a /RegExDot.RegEx.CaptureGroup/ is precisely specified, check whether the resulting minimum data-requirement is available. } deriving (Eq, Show) instance Data.Default.Default ExecutionOptions where def = setVerbose False $ ToolShed.Options.blankValue { abortTrialRepetitionsOnInherentFailure = True, -- Regrettably, this slightly reduces performance for most non-pathological patterns. catchIncompatibleAnchors = True, checkExistenceOfInelasticTail = True, checkForUnconsumableData = True, -- Expensive, particularly when (not requireMatchList), & only typically useful in failure-scenarios. moderateGreed = True, -- Cost may exceed benefit. TODO: confirm. preferAlternativesWhichFeedTheGreedy = True, preferAlternativesWhichMimickUnrolling = True, preferFewerRepeatedAlternatives = True, unrollRepeatedSingletonAlternative = True, -- Affects only efficiency, not the result. useFirstMatchAmongAlternatives = False, -- Perl-style matching may be faster, but may also yield a sub-optimal Match. validateMinConsumptionOfAlternatives = False -- The cost outweighs the small infrequent dividend. } instance ToolShed.Options.Options ExecutionOptions where blankValue = MkExecutionOptions { abortTrialRepetitionsOnInherentFailure = undefined, abortTrialRepetitionsOnZeroConsumption = undefined, bypassInputDataForLiberalConsumer = undefined, catchIncompatibleAnchors = undefined, checkExistenceOfInelasticTail = undefined, checkForUnconsumableData = undefined, moderateGreed = undefined, permitReorderingOfAlternatives = undefined, preferAlternativesWhichFeedTheGreedy = undefined, preferAlternativesWhichMimickUnrolling = undefined, preferFewerRepeatedAlternatives = undefined, requireMatchList = undefined, unrollRepeatedSingletonAlternative = undefined, useFirstMatchAmongAlternatives = undefined, validateMinConsumptionOfAlternatives = undefined } -- | Sets those fields which depend crucially on whether the caller wants to retrieve any /RegExDot.RegEx.MatchList/ from the /RegExDot.RegEx.Result/, or just query whether there is one. setVerbose :: Bool -> ExecutionOptions -> ExecutionOptions setVerbose verbose e = e { abortTrialRepetitionsOnZeroConsumption = verbose, -- The corresponding check, involves evaluation of a /RegExDot.RegEx.MatchList/, which is too expensive if the /RegExDot.RegEx.Matchlist/ isn't otherwise required. bypassInputDataForLiberalConsumer = not verbose, -- Potentially bypasses reading of /RegExDot.RegEx.InputData/, which is inappropriate if the mapping into a /RegExDot.RegEx.Result/ is required. permitReorderingOfAlternatives = not verbose, -- Doesn't help when 'requireMatchList', since an exhaustive search of /RegExDot.RegEx.Alternatives/, for the optimal solution, is performed. requireMatchList = verbose }