예제 #1
0
파일: Utils.cs 프로젝트: Serpen/Serpen.Uni
        public static void ExportToTemp(this IAcceptWord automat)
        {
            if (automat is IAutomat a2)
            {
                SaveAutomatImageToTemp(a2);
            }
            var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            var stream    = new System.IO.FileStream(System.Environment.ExpandEnvironmentVariables($@"%temp%\automat\{automat.Name}.bin"), System.IO.FileMode.Create, System.IO.FileAccess.Write);

            formatter.Serialize(stream, automat);
            stream.Close();
        }
예제 #2
0
파일: Utils.cs 프로젝트: Serpen/Serpen.Uni
 internal static void AcceptWordConsoleLine(this IAcceptWord A, string w, bool onlytrue = false)
 {
     try {
         bool accepts = A.AcceptWord(w);
         if (accepts || !onlytrue)
         {
             System.Console.WriteLine($"{A.Name} accepts |{w.Length}| '{w}': {accepts}");
         }
     } catch (Turing.TuringCycleException e) {
         System.Console.WriteLine($"{A.Name} {e.Message}");
     } catch (ContextFree.PDAStackException e) {
         System.Console.WriteLine($"{A.Name} {e.Message}");
     }
 }
예제 #3
0
 public bool SameAlphabet(IAcceptWord A2)
 {
     if (this.Terminals.Length != A2.Alphabet.Length)
     {
         return(false);
     }
     for (int i = 0; i < this.Terminals.Length; i++)
     {
         if (this.Terminals[i] != A2.Alphabet[i])
         {
             return(false);
         }
     }
     return(true);
 }
예제 #4
0
파일: Utils.cs 프로젝트: Serpen/Serpen.Uni
 internal static void DebugMessage(string message, IAcceptWord a, Serpen.Uni.Utils.eDebugLogLevel level)
 {
     if (Serpen.Uni.Utils.DebugLogLevel >= level && System.Diagnostics.Debugger.IsAttached)
     {
         var stack   = new System.Diagnostics.StackTrace(true);
         var sframe  = stack.GetFrame(1);
         var smethod = sframe.GetMethod();
         System.Diagnostics.Debug.WriteLine(
             smethod.DeclaringType.Name + "." +
             smethod.Name +
             ":" + sframe.GetFileLineNumber() + " " +
             (a != null ? "[" + a.Name + "] " : " ") +
             message);
     }
 }
예제 #5
0
파일: Tests.cs 프로젝트: Serpen/Serpen.Uni
        public static bool TestEqualWithWords(IAcceptWord A1, IAcceptWord A2, int initialCount = 100) {
            int onceTrue = 0, onceFalse = 0;
            int passLevel = System.Math.Min(initialCount / 10, 5);

            string[] words = System.Array.Empty<string>();
            int count = 0;

            if (A1 is CFGrammer cfg1) A1 = cfg1.ToChomskyNF();
            if (A2 is CFGrammer cfg2) A2 = cfg2.ToChomskyNF();

            while ((onceTrue < passLevel | onceFalse < passLevel) && count < initialCount * 2) {
                words = A1.GetRandomWords(initialCount / 2, 1, Serpen.Uni.Utils.Sqrt(initialCount), words);
                foreach (string w in words) {
                    try {
                        var erg1 = A1.AcceptWord(w);
                        var erg2 = A2.AcceptWord(w);

                        if (erg1) onceTrue++;
                        else onceFalse++;

                        if (erg1 != erg2)
                            throw new Automat.Exception($"{count}. word '{w}' divides Automates", A1, A2);

                        Utils.DebugMessage($"{count}. word '{w}' passes {erg1}", Uni.Utils.eDebugLogLevel.Verbose, A1, A2);
                        count++;
                    } catch (TuringCycleException) {
                    } catch (PDAStackException) { }
                }
            }
            if (onceTrue >= passLevel && onceFalse >= passLevel) {
                Utils.DebugMessage($"{count} words passed ({onceTrue}/{onceFalse})", Uni.Utils.eDebugLogLevel.Verbose, A1, A2);
                return true;
            } else {
                if (A1.Equals(A2)) {
                    Utils.DebugMessage($"{count} words passed, but not both tested ({onceTrue}/{onceFalse}), but Equals works", Uni.Utils.eDebugLogLevel.Verbose, A1, A2);
                    return true;
                } else {
                    Utils.DebugMessage($"{count} words passed, but not both tested ({onceTrue}/{onceFalse}), Equals not working", Uni.Utils.eDebugLogLevel.Normal, A1, A2);
                    return true;
                }

            }
        }
예제 #6
0
파일: Tests.cs 프로젝트: Serpen/Serpen.Uni
        public static bool InMyhillNerodeRelation(string w1, string w2, IAcceptWord automat, int count = 50) {
            var words = automat.GetRandomWords(count, 0, Serpen.Uni.Utils.Sqrt(count), System.Array.Empty<string>());

            foreach (string w in words) {
                bool? erg1 = null, erg2 = null;

                try {
                    erg1 = automat.AcceptWord(w1 + w);
                } catch (Turing.TuringCycleException) {
                } catch (ContextFree.PDAStackException) { }
                try {
                    erg2 = automat.AcceptWord(w2 + w);
                } catch (Turing.TuringCycleException) {
                } catch (ContextFree.PDAStackException) { }

                if (erg1 != erg2) {
                    Utils.DebugMessage($"word {w} divides {w1},{w2}", automat, Uni.Utils.eDebugLogLevel.Verbose);
                    return false;
                }
            }
            return true;
        }
예제 #7
0
파일: PDA.cs 프로젝트: Serpen/Serpen.Uni
        IAcceptWord JoinConcatUnion(IAcceptWord automat, JoinConcatUnionKind kind) {
            if (!(automat is PDA pda2))
                throw new System.NotSupportedException();
            if (kind != JoinConcatUnionKind.Join && !(automat is StatePDA))
                throw new System.NotSupportedException();
            if (this is StackPDA || automat is StackPDA)
                throw new System.NotImplementedException();
            // TODO: investigate more, State PDA is perfect Stack PDA seems complicated

            // TODO: what if A1 or A2 has a StackStartsymbol set, should it be transformed
            // to a transform or applied

            uint offsetA1 = 0; // first state of A2
            uint offsetA2 = this.StatesCount; // first state of A2
            if (kind == JoinConcatUnionKind.Union) {
                offsetA1 = 1;
                offsetA2++;
            }

            char[] inputAlphabet = this.Alphabet.Union(pda2.Alphabet).ToArray();
            char[] workAlphabet = this.WorkAlphabet.Union(pda2.WorkAlphabet).ToArray();

            var pdat = new PDATransform();

            uint startState;
            // Union: add new start state, with e to both starts
            if (kind == JoinConcatUnionKind.Union) {
                startState = 0;
                pdat.Add(0, null, null, null, this.StartState + offsetA1);
                pdat.AddM(0, null, null, null, pda2.StartState + offsetA2);
            } else
                startState = this.StartState;

            // add each D1 transform + offset of A1
            foreach (var item in this.Transforms)
                foreach (var val in item.Value)
                    pdat.AddM(item.Key.q + offsetA1, item.Key.ci, item.Key.cw, val.cw2, val.qNext + offsetA1);

            // add each D1 transform, + offset of A2
            foreach (var item in pda2.Transforms)
                foreach (var val in item.Value)
                    pdat.AddM(item.Key.q + offsetA2, item.Key.ci, item.Key.cw, val.cw2, val.qNext + offsetA2);


            uint[] accStates;
            if (kind == JoinConcatUnionKind.Concat)
                // Concat: has only accepted states from A2
                accStates = new uint[pda2.AcceptedStates.Length];
            else
                // Join, Union has A1, A2 accpted states
                accStates = new uint[this.AcceptedStates.Length + pda2.AcceptedStates.Length];

            int i = 0; // store where D1 acc ends
            // iterate A1 acc
            for (; i < this.AcceptedStates.Length; i++)
                if (kind == JoinConcatUnionKind.Concat)
                    // Concat: lead accepted states from A1 to A2 start
                    pdat.AddM(this.AcceptedStates[i] + offsetA1, null, null, null, pda2.StartState + offsetA2);
                else
                    // Join, Union: states from A1 are normal accepted
                    accStates[i] = this.AcceptedStates[i] + offsetA1;

            if (kind == JoinConcatUnionKind.Concat)
                i = 0;

            // iterate A2 acs and + offsetA2
            for (int j = 0; j < pda2.AcceptedStates.Length; j++)
                accStates[i + j] = (pda2.AcceptedStates[j] + offsetA2);

            if (this is StatePDA)
                return new StatePDA($"{kind.ToString()}({Name}+{pda2.Name})", this.StatesCount + pda2.StatesCount + offsetA1, inputAlphabet, workAlphabet, pdat, startState, pda2.StartSymbol, accStates);
            else if (this is StackPDA)
                return new StackPDA($"{kind.ToString()}({Name}+{pda2.Name})", this.StatesCount + pda2.StatesCount + offsetA1, inputAlphabet, workAlphabet, pdat, startState, pda2.StartSymbol);
            else
                throw new System.NotImplementedException();
        }
예제 #8
0
        CFGrammer Combine(IAcceptWord ia, string[] startBodysFormat, string nameExt) {
            if (!(ia is CFGrammer cfg2))
                throw new System.NotSupportedException();

            var newRules = new RuleSet();

            List<char> finalVars = this.Variables.ToList();
            List<char> finalTerms = this.Terminals.ToList();
            char newStart = Utils.NextFreeCapitalLetter(this.VarAndTerm.Union(cfg2.VarAndTerm), this.StartSymbol);

            finalVars.Add(newStart);

            var translate = new Dictionary<char, char>(cfg2.VarAndTerm.Count);
            foreach (char V in cfg2.Variables) {
                if (!finalVars.Contains(V)) {
                    finalVars.Add(V);
                    translate.Add(V, V);
                } else {
                    char newChar = Utils.NextFreeCapitalLetter(finalTerms.Union(finalVars), V);
                    translate.Add(V, newChar);
                    finalVars.Add(newChar);
                }
            }

            // assume char as terminal is equal when its equal
            foreach (char t in cfg2.Terminals) {
                if (!finalTerms.Contains(t)) {
                    finalTerms.Add(t);
                }
                // else {
                //     char newChar = Utils.NextFreeLowerLetter(finalTerms.Union(finalVars)); //against convention!
                //     translate.Add(t, newChar);
                //     finalTerms.Add(newChar);
                // }
                if (!translate.ContainsKey(t))
                    translate.Add(t, t);
            }


            for (int i = 0; i < startBodysFormat.Length; i++)
                startBodysFormat[i] = string.Format(startBodysFormat[i], this.StartSymbol, cfg2.StartSymbol, newStart);

            //New Start Rule, build 
            newRules.Add(newStart, startBodysFormat);


            foreach (var r in this.Rules) {
                newRules.Add(r.Key, r.Value);
            }


            foreach (var r in cfg2.Rules) {
                var newVals = new List<string>(r.Value.Length);
                foreach (string body in r.Value) {
                    var sw = new System.Text.StringBuilder();
                    foreach (char c in body)
                        sw.Append(translate[c]);

                    newVals.Add(sw.ToString());
                }
                newRules.Add(translate[r.Key], newVals.ToArray());
            }

            return new CFGrammer($"CFG_Combine({nameExt},{Name})", finalVars.ToArray(), finalTerms.ToArray(), newRules, newStart);

        }
예제 #9
0
파일: FABase.cs 프로젝트: Serpen/Serpen.Uni
        IAcceptWord JoinConcatUnion(IAcceptWord automat, JoinConcatUnionKind unionConcatJoinKind)
        {
            if (!(automat is FABase fa2))
            {
                throw new System.NotSupportedException();
            }

            uint offsetA1 = 0;                // first state of A2
            uint offsetA2 = this.StatesCount; // first state of A2

            if (unionConcatJoinKind == JoinConcatUnionKind.Union)
            {
                offsetA1 = 1;
                offsetA2++;
            }

            char[] inputAlphabet = this.Alphabet.Union(fa2.Alphabet).ToArray();

            var neaeT = new NFAeTransform();

            uint startState;

            // Union: add new start state, with e to both starts
            if (unionConcatJoinKind == JoinConcatUnionKind.Union)
            {
                startState = 0;
                neaeT.Add(0, null, this.StartState + offsetA1);
                neaeT.AddM(0, null, fa2.StartState + offsetA2);
            }
            else
            {
                startState = this.StartState;
            }

            // add each A1 transform + offset of A1
            foreach (var item in this.Transforms)
            {
                foreach (var val in item.Value)
                {
                    neaeT.AddM(item.Key.q + offsetA1, item.Key.c, val + offsetA1);
                }
            }

            // add each A1 transform, + offset of A2
            foreach (var item in fa2.Transforms)
            {
                foreach (var val in item.Value)
                {
                    neaeT.AddM(item.Key.q + offsetA2, item.Key.c, val + offsetA2);
                }
            }


            uint[] accStates;
            if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
            {
                // Concat: has only accepted states from A2
                accStates = new uint[fa2.AcceptedStates.Length];
            }
            else
            {
                // Join, Union has A1, A2 accpted states
                accStates = new uint[this.AcceptedStates.Length + fa2.AcceptedStates.Length];
            }

            int i = 0; // store where D1 acc ends

            // iterate A1 acc
            for (; i < this.AcceptedStates.Length; i++)
            {
                if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
                {
                    // Concat: lead accepted states from A1 to A2 start
                    neaeT.AddM(this.AcceptedStates[i] + offsetA1, null, fa2.StartState + offsetA2);
                }
                else
                {
                    // Join, Union: states from A1 are normal accepted
                    accStates[i] = this.AcceptedStates[i] + offsetA1;
                }
            }

            if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
            {
                i = 0;
            }

            // iterate A2 acs and + offsetA2
            for (int j = 0; j < fa2.AcceptedStates.Length; j++)
            {
                accStates[i + j] = (fa2.AcceptedStates[j] + offsetA2);
            }


            return(new NFAe($"NEAe{unionConcatJoinKind.ToString()}({Name}+{fa2.Name})", this.StatesCount + fa2.StatesCount + offsetA1, inputAlphabet, neaeT, startState, accStates));
        }