コード例 #1
0
ファイル: PDA.cs プロジェクト: Serpen/Serpen.Uni
        public IAcceptWord Reverse() {
            var pdat = new PDATransform();

            string[] names = new string[this.StatesCount + 1];

            //array pointer old to new state            
            uint[] newstate = new uint[this.StatesCount];
            for (uint i = 0; i < newstate.Length; i++) {
                newstate[i] = this.StatesCount - i;
                names[i + 1] = (newstate[i] - 1).ToString();
            }
            names[0] = "new";

            //turn and add each transform
            foreach (var dt in this.Transforms.Reverse())
                foreach (var dtv in dt.Value)
                    pdat.AddM(newstate[dtv.qNext], dt.Key.ci, dt.Key.cw, dtv.cw2, newstate[dt.Key.q]);

            //start state is qe, which leads to every old accepted state
            for (int i = 0; i < this.AcceptedStates.Length; i++)
                pdat.AddM(0, null, null, null, newstate[this.AcceptedStates[i]]);

            if (this is StatePDA)
                return new StatePDA($"Reverse({Name})", names, this.Alphabet, this.WorkAlphabet, pdat, 0, this.StartSymbol, new uint[] { this.StatesCount });
            else if (this is StackPDA)
                return new StackPDA($"Reverse({Name})", names, this.Alphabet, this.WorkAlphabet, pdat, 0, this.StartSymbol);
            else
                throw new System.NotImplementedException();
        }
コード例 #2
0
        public override IAutomat PurgeStates()
        {
            (uint[] translate, string[] names, _) = base.RemovedStateTranslateTables();

            var newT = new PDATransform();

            foreach (var t2 in Transforms)
            {
                if (translate.Contains(t2.Key.q))
                {
                    foreach (var v in t2.Value)
                    {
                        if (translate.Contains(v.qNext))
                        {
                            newT.AddM(translate.ArrayIndex(t2.Key.q), t2.Key.ci, t2.Key.cw, v.cw2, translate.ArrayIndex(v.qNext));
                        }
                    }
                }
            }

            return(new StackPDA($"{Name}_purged", names, Alphabet, WorkAlphabet, newT, translate.ArrayIndex(StartState), StartSymbol));
        }
コード例 #3
0
        public static StackPDA GenerateRandom()
        {
            const byte MAX_STATES = 20;
            const byte MAX_CHAR   = 7;

            var rnd = Uni.Utils.RND;

            var t          = new PDATransform();
            int stateCount = rnd.Next(1, MAX_STATES);

            char[] inputAlphabet = new char[rnd.Next(1, MAX_CHAR)];
            for (int i = 0; i < inputAlphabet.Length; i++)
            {
                inputAlphabet[i] = (char)rnd.Next('a', 'z');
            }
            inputAlphabet = inputAlphabet.Distinct().ToArray();

            char[] workAlphabet = new char[rnd.Next(1, MAX_CHAR)];
            for (int i = 1; i < workAlphabet.Length; i++)
            {
                workAlphabet[i] = (char)rnd.Next('a', 'z');
            }
            workAlphabet[0] = START;
            workAlphabet    = workAlphabet.Distinct().ToArray();

            for (uint i = 0; i < stateCount; i++)
            {
                int transformsRnd = rnd.Next(0, inputAlphabet.Length);
                for (int j = 0; j < transformsRnd; j++)
                {
                    t.AddM(i, inputAlphabet.RndElement(), workAlphabet.RndElement(), workAlphabet.RndElement().ToString(), (uint)rnd.Next(0, stateCount));
                }
            }

            var ret = new StackPDA("SPDA_Random", (uint)stateCount, inputAlphabet, workAlphabet, t, (uint)rnd.Next(0, stateCount), START);

            ret.Name = $"SPDA_Random_{ret.GetHashCode()}";
            return(ret);
        }
コード例 #4
0
 public StatePDA(string name, uint StatesCount, char[] InputAlphabet, char[] Workalphabet, PDATransform Transform, uint StartState, char?Startstacksymbol, params uint[] AcceptedStates)
     : base(name, StatesCount, InputAlphabet, Workalphabet, Transform, StartState, Startstacksymbol, AcceptedStates)
 {
 }
コード例 #5
0
 public StatePDA(string name, string[] names, char[] InputAlphabet, char[] Workalphabet, PDATransform Transform, uint StartState, params uint[] AcceptedStates)
     : base(name, names, InputAlphabet, Workalphabet, Transform, StartState, null, AcceptedStates)
 {
 }
コード例 #6
0
ファイル: PDA.cs プロジェクト: Serpen/Serpen.Uni
        protected PDA(string name, string[] states, char[] inputAlphabet, char[] workalphabet, PDATransform transform, uint startState, char? startStackSymbol, uint[] acceptedStates)
        : base(name, states, inputAlphabet, startState, acceptedStates) {
            this.WorkAlphabet = workalphabet;
            if (startStackSymbol.HasValue && !workalphabet.Contains(startStackSymbol.Value))
                this.WorkAlphabet = this.WorkAlphabet.Append(startStackSymbol.Value).ToArray();
            this.Transforms = transform;
            this.StartSymbol = startStackSymbol;

            CheckConstraints();
        }
コード例 #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
 public StackPDA(string name, string[] states, char[] InputAlphabet, char[] Workalphabet, PDATransform Transform, uint StartState)
     : base(name, states, InputAlphabet, Workalphabet, Transform, StartState, null, new uint[] { })
 {
 }
コード例 #9
0
 /// <summary>
 /// Create PDA which accepts by empty stack
 /// </summary>
 /// <param name="StatesCount">How many states</param>
 /// <param name="InputAlphabet">Input Alphabet for Word processing</param>
 /// <param name="Workalphabet">Work Alphabet for Stack</param>
 /// <param name="Transform"></param>
 /// <param name="StartState">State from which to start</param>
 /// <param name="Startsymbol">Inital Stack Population</param>
 public StackPDA(string name, uint StatesCount, char[] InputAlphabet, char[] Workalphabet, PDATransform Transform, uint StartState, char?Startsymbol)
     : base(name, StatesCount, InputAlphabet, Workalphabet, Transform, StartState, Startsymbol, new uint[] { })
 {
 }