예제 #1
0
        /// <summary>
        /// Gets if the two specified expressions are equivalent. This function reduces and subsitutes 
        /// given expressions and the stack as needed to get an accurate result.
        /// </summary>
        public static FuzzyBool Equivalent(ref Expression A, ref Expression B, IVariableStack<Expression> Stack)
        {
            if (A == B)
            {
                return FuzzyBool.True;
            }

            while (true)
            {
                // Variable equality
                VariableExpression va = A as VariableExpression;
                if (va != null)
                {
                    VariableExpression vb = B as VariableExpression;
                    if (vb != null)
                    {
                        if (va.Index == vb.Index)
                        {
                            return FuzzyBool.True;
                        }
                    }
                }

                // Tuple equality
                TupleExpression at = A as TupleExpression;
                if (at != null)
                {
                    TupleExpression bt = B as TupleExpression;
                    if (bt != null)
                    {
                        if (at.Parts.Length != bt.Parts.Length)
                        {
                            return FuzzyBool.False;
                        }
                        for (int t = 0; t < at.Parts.Length; t++)
                        {
                            FuzzyBool pe = Equivalent(ref at.Parts[t], ref bt.Parts[t], Stack);
                            if (pe == FuzzyBool.False)
                            {
                                return FuzzyBool.False;
                            }
                            if (pe == FuzzyBool.Undetermined)
                            {
                                return FuzzyBool.Undetermined;
                            }
                        }
                        return FuzzyBool.True;
                    }
                }

                // Tuple break
                TupleBreakExpression atb = A as TupleBreakExpression;
                if (atb != null)
                {
                    TupleBreakExpression btb = B as TupleBreakExpression;
                    if (btb != null)
                    {
                        return FuzzyBoolLogic.And(
                            Expression.Equivalent(ref atb.SourceTuple, ref btb.SourceTuple, Stack),
                            Expression.Equivalent(ref atb.InnerExpression, ref btb.InnerExpression, Stack));
                    }
                }

                // Function definition equality
                FunctionDefineExpression afd = A as FunctionDefineExpression;
                if (afd != null)
                {
                    FunctionDefineExpression bfd = B as FunctionDefineExpression;
                    if (bfd != null)
                    {
                        if (afd.ArgumentIndex == bfd.ArgumentIndex)
                        {
                            var nstack = Stack.Cut(afd.ArgumentIndex).Append(new Expression[] { Expression.Variable(afd.ArgumentIndex) });
                            return FuzzyBoolLogic.And(
                                Expression.Equivalent(ref afd.ArgumentType, ref bfd.ArgumentType, nstack),
                                Expression.Equivalent(ref afd.Function, ref bfd.Function, nstack));
                        }
                    }
                }

                // Nothing yet? try reducing
                if (A.Reduce(Stack, ref A) | B.Reduce(Stack, ref B))
                {
                    continue;
                }
                else
                {
                    break;
                }
            }

            return FuzzyBool.Undetermined;
        }
예제 #2
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     Expression sifunc;
     Expression itype;
     this.Function.TypeCheck(
         TypeStack.Cut(this.ArgumentIndex).Append(new Expression[] { this.ArgumentType }),
         Stack.Cut(this.ArgumentIndex).Append(new Expression[] { Expression.Variable(Stack.NextFreeIndex) }),
         out sifunc, out itype);
     Type = Expression.FunctionType(this.ArgumentIndex, this.ArgumentType, itype);
     TypeSafeExpression = new FunctionDefineExpression(this.ArgumentIndex, this.ArgumentType, sifunc);
 }
예제 #3
0
파일: Tuple.cs 프로젝트: dzamkov/SaltScript
        public override void TypeCheck(
            IVariableStack<Expression> TypeStack, 
            IVariableStack<Expression> Stack, 
            out Expression TypeSafeExpression, out Expression Type)
        {
            Expression stuple;
            Expression tupletype;
            this.SourceTuple.TypeCheck(TypeStack, Stack, out stuple, out tupletype);

            TupleExpression te;
            while ((te = tupletype as TupleExpression) == null && tupletype.Reduce(Stack, ref tupletype)) ;
            if (te == null)
            {
                throw new NotImplementedException();
            }

            TupleExpression se;
            while ((se = stuple as TupleExpression) == null && stuple.Reduce(Stack, ref stuple)) ;
            Expression[] stackappend;
            if (se != null)
            {
                stackappend = se.Parts ?? new Expression[0];
                if (stackappend.Length != this.TupleSize)
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                if (te.Parts.Length != this.TupleSize)
                {
                    throw new NotImplementedException();
                }

                stackappend = new Expression[te.Parts.Length];
                int ni = Stack.NextFreeIndex;
                for (int t = 0; t < te.Parts.Length; t++)
                {
                    stackappend[t] = Expression.Variable(t + ni);
                }
            }

            Expression si;
            Expression itype;
            this.InnerExpression.TypeCheck(
                TypeStack.Cut(this.BreakIndex).Append(te.Parts ?? new Expression[0]),
                Stack.Cut(this.BreakIndex).Append(stackappend),
                out si,
                out itype);

            TypeSafeExpression = new TupleBreakExpression(this.BreakIndex, this.TupleSize, stuple, si);
            Type = itype;
        }