-- |-- Copyright : (c) 2010, 2011 Benedikt Schmidt-- License : GPL v3 (see LICENSE)-- -- Maintainer : Benedikt Schmidt <beschmi@gmail.com>---- Completeness and minimality checking for the variants of a term.moduleTerm.Narrowing.Variants.Check(checkComplete,checkMinimal,variantsFrom,isNormalInstance,leqSubstVariant)whereimportTerm.SubstitutionimportTerm.UnificationimportTerm.Rewriting.NormimportTerm.Subsumption(factorSubstVia,canonizeSubst)importTerm.Narrowing.NarrowimportExtension.PreludeimportUtils.MiscimportControl.BasicsimportControl.Monad.ReaderimportData.ListimportDebug.Trace.Ignore-- Variant Order------------------------------------------------------------------------ | @isNormalInstance t s s'@ returns @True@ if @s'(norm(s(t)))@ is in normal-- form.isNormalInstance::LNTerm->LNSubst->LNSubst->WithMaudeBoolisNormalInstancetss'={- trace ("isnormalInstance " ++ show (t,s,s')) $ -}dot'<-norm'(applyVTermst)nf'(applyVTerms't')-- | @leqSubstVariant t s1 s2@ compares two substitutions using the variant order -- with respect to @t@ and returns @True@ if @s1@ is less or equal than @s2@-- and @False@ otherwise. Use the more expensive @compareSubstVariant@-- which uses two AC matchings instead of one if you also want to distinguish-- @Nothing@, @Just EQ@, and @Just GT@.-- -- s1 is smaller or equal to s2 wrt. to the variant order (less general) iff there-- is an s1' such that s1 = s2' . s2 restricted to vars(t) and s2'(norm(s2(t)))-- is in normal form, or equivalently norm(s1(t)) =AC= s2'(norm(s2(1))). This-- means s1 is redundant since it is just an AC instance of s2 that does-- not "require additional normalization steps."leqSubstVariant::LNTerm->LNSubstVFresh->LNSubstVFresh->WithMaudeBoolleqSubstVariantts1_0s2_0=reader$\hnd->s1_0==s2_0||any(\s->isNormalInstancets2s`runReader`hnd)({- (\x -> trace (show x) x) -}(factorSubstViatvarss1s2`runReader`hnd))wheretvars=freests1=restrictVFreshtvarss1_0`freshToFreeAvoiding`ts2=restrictVFreshtvarss2_0`freshToFreeAvoiding`t-- Completeness checking for a set of variants------------------------------------------------------------------------ | @checkComplete t substs@ checks if @substs@ is a complete set of variants-- for @t@ and returns @Just (subst1,subst2)@ if there is a narrowing step-- from @subst1@ that yields a new variant @subst2@.checkComplete::LNTerm->[LNSubstVFresh]->WithMaudeBoolcheckCompletetsubsts0=reader$\hnd->letnewSubsts=concatMap((`runReader`hnd).variantsFromt)substssubsts=sortOn(size&&&length.varsRangeVFresh)substs0inemptySubstVFresh`elem`substs0&&all(\s->not$isMaximalInssubstst`runReader`hnd)newSubsts-- | @variantsFrom rules t subst@ returns all the "one-step variants" of-- @norm (t subst)@ for the given set of @rules@.variantsFrom::LNTerm->LNSubstVFresh->WithMaude[LNSubstVFresh]variantsFromtsubstFrom0=reader$\hnd->(\res->trace(show("variantsFrom",t,substFrom0,res))res)$sortednub$doletsubstFrom=substFrom0`freshToFreeAvoiding`tsubstTo0<-(narrowSubsts=<<(norm'(applyVTermsubstFromt)))`runReader`hndletsubstTo=restrictVFresh(freest)$composeVFreshsubstTo0substFromguard(nfSubstVFresh'substTo`runReader`hnd)-- prune substitutions that are not in normal-formreturn$canonizeSubst$removeRenamings$substTo-- | @isMaximalIn s substs t@ returns @True@ if @s@ is minimal in substs wrt.-- <_Var^t, i.e., the function returns @True@ if there is no s'-- in substs with s' <=_Var^t s.isMaximalIn::LNSubstVFresh->[LNSubstVFresh]->LNTerm->WithMaudeBoolisMaximalInssubstst=reader$\hnd->all(\s'->(\res->trace(show("isMaximal:",notres,"=",s,"<=",s'))res)$not(leqSubstVarianttss'`runReader`hnd))substs-- Minimality checking for a set of variants------------------------------------------------------------------------ | @checkMinimal t substs@ checks if @substs@ is a minimal set of variants-- for @t@ and returns @False@ if there are subst1 /= subst2 in substs with-- subst1 <=_Var_t subst2.checkMinimal::LNTerm->[LNSubstVFresh]->WithMaudeBoolcheckMinimaltsubsts=reader$\hnd->noDuplicatessubsts&&all(\s->(\res->trace(show(s,substs,res))res)$(`runReader`hnd)$isMaximalIns(deletessubsts)t)substs