예제 #1
0
   private static bool ProcessAcUnificationStep(UnificationContinuation currentProblem, Queue<UnificationContinuation> currentContinuations, 
 Func<UnificationContinuation, Equation, bool> processFail, Equation currEq)
   {
       var acLhs = currEq.Lhs as TrsAcTerm;
         var acRhs = currEq.Rhs as TrsAcTerm;
         bool fail = false;
         if (acLhs.Name != acRhs.Name)
         {
       fail = !processFail(currentProblem, currEq);
         }
         else
         {
       // Reduce cardinalities to reduce number of permutations
       foreach (var pair in (from lhsTerm in acLhs.OnfArguments
                        join rhsTerm in acRhs.OnfArguments
                          on lhsTerm.Term equals rhsTerm.Term
                         where lhsTerm.Term.IsGroundTerm
                           && rhsTerm.Term.IsGroundTerm
                         select new {
                           Lhs = lhsTerm,
                           Rhs = rhsTerm
                         }).ToList())
       {
         var diff = Math.Min(pair.Lhs.Cardinality, pair.Rhs.Cardinality);
         if (pair.Lhs.Cardinality > diff) pair.Lhs.Cardinality -= diff;
         else acLhs.OnfArguments.Remove(pair.Lhs);
         if (pair.Rhs.Cardinality > diff) pair.Rhs.Cardinality -= diff;
         else acRhs.OnfArguments.Remove(pair.Rhs);
       }
       // AC partitioning can only take place from the small to the large cardinalities
       List<TrsTermBase> fromArgs = null;
       List<TrsTermBase> toArgs = null;
       if (acLhs.TotalCardinality > acRhs.TotalCardinality)
       {
         fromArgs = acRhs.ExpandedArguments;
         toArgs = acLhs.ExpandedArguments;
       }
       else
       {
         fromArgs = acLhs.ExpandedArguments;
         toArgs = acRhs.ExpandedArguments;
       }
       // Generate mappings ... this is where the AC semantics are applied
       var setPartitionMappings = new SetMapPartitionEnumerator<int, int>(new HashSet<int>(Enumerable.Range(0, fromArgs.Count)),
         new HashSet<int>(Enumerable.Range(0, toArgs.Count)));
       // The first mapping will map to the first continuation, this must be added to the
       // current problem's equations in order to preserve algorithm correctness when the unification result
       // contains no substitutions.
       var isFirstContinuation = true;
       var initialCurrentProblem = currentProblem.CreateCopy(); // currentProblem gets updated in the first iteration
       foreach (var mappings in setPartitionMappings)
       {
         // Cater for multiple unification problems generated by the current AC problem
         UnificationContinuation clone = null;
         if (!isFirstContinuation) clone = initialCurrentProblem.CreateCopy();
         foreach (var mapping in mappings)
         {
       Equation eq = new Equation();
       eq.Lhs = fromArgs[mapping.FromElement];
       if (mapping.ToPartition.Count == 1) eq.Rhs = toArgs[mapping.ToPartition.First()];
       else eq.Rhs = new TrsAcTerm(acLhs.Name, mapping.ToPartition.Select(i => toArgs[i]));
       if (!isFirstContinuation) clone.CurrentEquations.Add(eq);
       else currentProblem.CurrentEquations.Add(eq);
         }
         if (!isFirstContinuation) currentContinuations.Enqueue(clone);
         else isFirstContinuation = false;
       }
         }
         return fail;
   }
예제 #2
0
        /// <summary>
        /// Applies the custom unifiers for the current equation in case of failiure ...
        /// it applies the first working unifier from the list of custom unifiers.
        /// </summary>
        private List <UnificationContinuation> CustomFail(UnificationContinuation currentProblem, Equation currEq, List <TrsVariable> variableNamesToPreserve)
        {
            // First try custom unifiers ... use the first one that works.
            HashSet <UnificationResult> unificationResults = new HashSet <UnificationResult>();

            foreach (var unifFunc in customUnifiers)
            {
                // Prevent overwriting of input terms ...
                var input    = currEq.CreateCopy();
                var unifiers = unifFunc.GetUnifier(input.Lhs, input.Rhs);
                if (unifiers != null)
                {
                    foreach (var result in unifiers)
                    {
                        if (result.Succeed)
                        {
                            if (result.Unifier == null)
                            {
                                result.Unifier = new List <Substitution>();
                            }
                            unificationResults.Add(result);
                        }
                    }
                }
            }
            unificationResults = new HashSet <UnificationResult>(unificationResults.Where(result => result.Succeed));
            if (unificationResults.Count == 0)
            {
                return(new List <UnificationContinuation>());
            }
            else
            {
                var retContinuations = new HashSet <UnificationContinuation>();
                foreach (var customUnifier in unificationResults)
                {
                    bool succeed = true;
                    foreach (var customSubstitution in customUnifier.Unifier)
                    {
                        // Do occurs check
                        if (customSubstitution.SubstitutionTerm.ContainsVariable(customSubstitution.Variable))
                        {
                            succeed = false;
                            break;
                        }
                        // Prevent conflicting mappings
                        foreach (var substitution in currentProblem.CurrentSubstitutions)
                        {
                            if (substitution.Variable.Equals(customSubstitution.Variable) &&
                                !substitution.SubstitutionTerm.Equals(customSubstitution.SubstitutionTerm))
                            {
                                succeed = false;
                                break;
                            }
                        }
                    }
                    // Apply the subtitutions
                    if (succeed)
                    {
                        // Create continuations here for injection back into the main algorithm loop
                        UnificationContinuation currentContinuation = currentProblem.CreateCopy();
                        foreach (var substitution in customUnifier.Unifier)
                        {
                            ProcessSubstitutionStep(currentContinuation, new Equation {
                                Lhs = substitution.Variable, Rhs = substitution.SubstitutionTerm
                            }, variableNamesToPreserve);
                        }
                        retContinuations.Add(currentContinuation);
                    }
                }
                return(retContinuations.ToList());
            }
        }
예제 #3
0
 /// <summary>
 /// Applies the custom unifiers for the current equation in case of failiure ... 
 /// it applies the first working unifier from the list of custom unifiers.
 /// </summary>
 private List<UnificationContinuation> CustomFail(UnificationContinuation currentProblem, Equation currEq, List<TrsVariable> variableNamesToPreserve)
 {
     // First try custom unifiers ... use the first one that works.
       HashSet<UnificationResult> unificationResults = new HashSet<UnificationResult>();
       foreach (var unifFunc in customUnifiers)
       {
     // Prevent overwriting of input terms ...
     var input = currEq.CreateCopy();
     var unifiers = unifFunc.GetUnifier(input.Lhs, input.Rhs);
     if (unifiers != null)
     {
       foreach (var result in unifiers)
     if (result.Succeed)
     {
       if (result.Unifier == null) result.Unifier = new List<Substitution>();
       unificationResults.Add(result);
     }
     }
       }
       unificationResults = new HashSet<UnificationResult>(unificationResults.Where(result => result.Succeed));
       if (unificationResults.Count == 0)
       {
     return new List<UnificationContinuation>();
       }
       else
       {
     var retContinuations = new HashSet<UnificationContinuation>();
     foreach (var customUnifier in unificationResults)
     {
       bool succeed = true;
       foreach (var customSubstitution in customUnifier.Unifier)
       {
     // Do occurs check
     if (customSubstitution.SubstitutionTerm.ContainsVariable(customSubstitution.Variable))
     {
       succeed = false;
       break;
     }
     // Prevent conflicting mappings
     foreach (var substitution in currentProblem.CurrentSubstitutions)
     {
       if (substitution.Variable.Equals(customSubstitution.Variable)
         && !substitution.SubstitutionTerm.Equals(customSubstitution.SubstitutionTerm))
       {
         succeed = false;
         break;
       }
     }
       }
       // Apply the subtitutions
       if (succeed)
       {
     // Create continuations here for injection back into the main algorithm loop
     UnificationContinuation currentContinuation = currentProblem.CreateCopy();
     foreach (var substitution in customUnifier.Unifier)
       ProcessSubstitutionStep(currentContinuation, new Equation { Lhs = substitution.Variable, Rhs = substitution.SubstitutionTerm }, variableNamesToPreserve);
     retContinuations.Add(currentContinuation);
       }
     }
     return retContinuations.ToList();
       }
 }
예제 #4
0
        private static bool ProcessAcUnificationStep(UnificationContinuation currentProblem, Queue <UnificationContinuation> currentContinuations,
                                                     Func <UnificationContinuation, Equation, bool> processFail, Equation currEq)
        {
            var  acLhs = currEq.Lhs as TrsAcTerm;
            var  acRhs = currEq.Rhs as TrsAcTerm;
            bool fail  = false;

            if (acLhs.Name != acRhs.Name)
            {
                fail = !processFail(currentProblem, currEq);
            }
            else
            {
                // Reduce cardinalities to reduce number of permutations
                foreach (var pair in (from lhsTerm in acLhs.OnfArguments
                                      join rhsTerm in acRhs.OnfArguments
                                      on lhsTerm.Term equals rhsTerm.Term
                                      where lhsTerm.Term.IsGroundTerm &&
                                      rhsTerm.Term.IsGroundTerm
                                      select new {
                    Lhs = lhsTerm,
                    Rhs = rhsTerm
                }).ToList())
                {
                    var diff = Math.Min(pair.Lhs.Cardinality, pair.Rhs.Cardinality);
                    if (pair.Lhs.Cardinality > diff)
                    {
                        pair.Lhs.Cardinality -= diff;
                    }
                    else
                    {
                        acLhs.OnfArguments.Remove(pair.Lhs);
                    }
                    if (pair.Rhs.Cardinality > diff)
                    {
                        pair.Rhs.Cardinality -= diff;
                    }
                    else
                    {
                        acRhs.OnfArguments.Remove(pair.Rhs);
                    }
                }
                // AC partitioning can only take place from the small to the large cardinalities
                List <TrsTermBase> fromArgs = null;
                List <TrsTermBase> toArgs   = null;
                if (acLhs.TotalCardinality > acRhs.TotalCardinality)
                {
                    fromArgs = acRhs.ExpandedArguments;
                    toArgs   = acLhs.ExpandedArguments;
                }
                else
                {
                    fromArgs = acLhs.ExpandedArguments;
                    toArgs   = acRhs.ExpandedArguments;
                }
                // Generate mappings ... this is where the AC semantics are applied
                var setPartitionMappings = new SetMapPartitionEnumerator <int, int>(new HashSet <int>(Enumerable.Range(0, fromArgs.Count)),
                                                                                    new HashSet <int>(Enumerable.Range(0, toArgs.Count)));
                // The first mapping will map to the first continuation, this must be added to the
                // current problem's equations in order to preserve algorithm correctness when the unification result
                // contains no substitutions.
                var isFirstContinuation   = true;
                var initialCurrentProblem = currentProblem.CreateCopy(); // currentProblem gets updated in the first iteration
                foreach (var mappings in setPartitionMappings)
                {
                    // Cater for multiple unification problems generated by the current AC problem
                    UnificationContinuation clone = null;
                    if (!isFirstContinuation)
                    {
                        clone = initialCurrentProblem.CreateCopy();
                    }
                    foreach (var mapping in mappings)
                    {
                        Equation eq = new Equation();
                        eq.Lhs = fromArgs[mapping.FromElement];
                        if (mapping.ToPartition.Count == 1)
                        {
                            eq.Rhs = toArgs[mapping.ToPartition.First()];
                        }
                        else
                        {
                            eq.Rhs = new TrsAcTerm(acLhs.Name, mapping.ToPartition.Select(i => toArgs[i]));
                        }
                        if (!isFirstContinuation)
                        {
                            clone.CurrentEquations.Add(eq);
                        }
                        else
                        {
                            currentProblem.CurrentEquations.Add(eq);
                        }
                    }
                    if (!isFirstContinuation)
                    {
                        currentContinuations.Enqueue(clone);
                    }
                    else
                    {
                        isFirstContinuation = false;
                    }
                }
            }
            return(fail);
        }