Package fmg.fmg8.endlAutomat.script

Source Code of fmg.fmg8.endlAutomat.script.ScriptInterpreter

/*
* File:             ScriptInterpreter.java
* Author:           Lukas K�nig
* Java version:     6.0
* Generated:        18.06.2008
*
* (c) Lukas K�nig, copyright according to GNU Lesser General Public License
* (LGPL) -> http://www.gnu.org/licenses/lgpl.html
*/

package fmg.fmg8.endlAutomat.script;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;


import fmg.fmg8.endlAutomat.EndlicherAutomat;
import fmg.fmg8.endlAutomat.Transition;
import fmg.fmg8.endlAutomat.ZInfo;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.conditions.ConstLeaf;
import fmg.fmg8.endlAutomat.conditions.InnerNode;
import fmg.fmg8.graphVis.graph.Knoten;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.sonstiges.Zwischenablage;
import fmg.fmg8.statistik.Parametersatz;

/**
* Implements an interpreter for a script language for automata construction.
*
* @author Lukas K�nig
*/
public class ScriptInterpreter {
   
    /**
     * The instruction counter.
     */
    private int instrCounter;
   
    /**
     * Counter.
     */
    private int paramCounter;
   
    /**
     * Counter.
     */
    private int ageCounter;
   
    /**
     * The parameters.
     */
    private Parametersatz pars;
   
    /**
     * The current ScriptCondition.
     */
    private ScriptCondition cond;
   
    /**
     * Der Modus, Verhalten oder Translator.
     */
    private int modus;
   
    /**
     * Verhaltensautomaten-Modus.
     */
    public static final int MODUS_VERHALTEN
        = SonstMeth.MODUS_VERHALTEN;
   
    /**
     * �bersetzermodus.
     */
    public static final int MODUS_TRANSLATOR
        = SonstMeth.MODUS_TRANSLATOR;
   
    /**
     * Flag, dass markiert, ob gerade eine Bedingung existiert, die nicht
     * einer Kante zugewiesen wurde.
     */
    public boolean condWaiting;
   
    /**
     * Constructor.
     *
     * @param params  The parameters.
     * @param mod     Der Modus (�bersetzer oder Verhalten).
     */
    public ScriptInterpreter(
            final Parametersatz params,
            final int mod) {
        this.pars = params;
        this.cond = new ScriptCondition(this.pars, mod);
        this.modus = mod;
        this.reset();
    }
   
    /**
     * Resets class vasiables.
     */
    private void reset() {
        this.instrCounter = 0;
        this.paramCounter = 0;
        this.ageCounter = 0;
        this.condWaiting = false;
        this.cond.reset();
    }
   
    /**
     * @param num  Number to normalize.
     *
     * @return  Normalized number.
     */
    private int normalize(final int num) {
        int i = num % 256;
       
        if (i <= 0) {
            i = 1;
        }
       
        return i;
    }
   
    /**
     * Inserts a node into the automaton.
     *
     * @param nam  The name of the node.
     * @param aut  The automaton to be altered.
     */
    private void insertNode(final int nam, final EndlicherAutomat aut) {
        int aktion = SonstMeth.modZwischen(
                this.instrCounter,
                SonstMeth.minBef(this.modus),
                SonstMeth.maxBef(this.modus));
       
        int param = this.paramCounter % 256 + 1;
        int alt = this.ageCounter % 256 + 1;
       
        if (param == 256) {
            param = 1;
        }
       
        if (alt == 256) {
            alt = 1;
        }
       
        aut.einfuegenKnoten(nam, aktion, param, alt);
       
        if (nam <= 0) {
            throw new RuntimeException("Knoten " + nam + " nicht eingef�gt.");
        }
       
        if (aut.holeStartzustand() == null) {
            aut.setStart(aut.holeKnoten(nam));
        }

        if (this.instrCounter
            % (SonstMeth.maxBef(this.modus) - SonstMeth.minBef(this.modus) + 1)
              == SonstMeth.maxBef(this.modus) - SonstMeth.minBef(this.modus)) {
            this.paramCounter++;
        }

        if (this.paramCounter % 10 == 9) {
            this.ageCounter++;
        }

        this.instrCounter++;
    }
   
    /**
     * Inserts an edge.
     *
     * @param knotNam1  Source node.
     * @param knotNam2  Target node.
     * @param aut       The automaton.
     */
    private void insertEdge(final int knotNam1,
                            final int knotNam2,
                            final EndlicherAutomat aut) {
        Knoten knot1 = aut.holeKnoten(knotNam1);
        Knoten knot2 = aut.holeKnoten(knotNam2);
        Condition c;
       
        if (knot1 == null) {
            this.insertNode(knotNam1, aut);
        }
        if (knot2 == null) {
            this.insertNode(knotNam2, aut);
        }
       
        c = this.cond.getCondition();
       
        aut.einfuegKante(knotNam1,
                         knotNam2,
                         c,
                         1);

        this.cond.reset();
       
        this.condWaiting = false;
       
        this.instrCounter++;
    }
   
    /**
     * Changes a part of a node.
     *
     * @param mode      Denotes which part of the node should be changed.
     *                  1: instruction,
     *                  2: parameter,
     *                  3: additional parameter.
     * @param knotNam   Node to be changed.
     * @param setValue  Value to set.
     * @param aut       Automaton.
     */
    private void changeNode(final int mode,
                            final int knotNam,
                            final int setValue,
                            final EndlicherAutomat aut) {
       
        Knoten knot = aut.holeKnoten(knotNam);
        ZInfo zusatz;
        int set;
        int setInst;
       
        if (knot == null) {
            this.insertNode(knotNam, aut);
            knot = aut.holeKnoten(knotNam);
        }
       
        zusatz = knot.getInfo();
        set = setValue % 256;
        if (set == 0) {
            set++;
        }

        if (mode == 1) { // Change instruction.
            setInst = SonstMeth.modZwischen(
                    setValue,
                    SonstMeth.minBef(this.modus),
                    SonstMeth.maxBef(this.modus));
            zusatz.setAkt(setInst);
        }
        if (mode == 2) { // Change parameter.
            zusatz.setPar(set);
        }
        if (mode == 3) { // Change additional parameter.
            zusatz.setAlter(set);
        }

        this.instrCounter++;
    }
   
    /**
     * Adds a token to the current Condition. If condition is null, creates a
     * new Condition.
     *
     * @param token  The token to add.
     */
    private void addCondTok(final Integer token) {
        this.cond.addToken(token);
        this.condWaiting = true;
    }
   
    /**
     * F�gt eine Kante zwischen Quell- und Zielknoten ein, die die Bedingungen
     * c1, c2, ... aller ausgehenden Kanten des Quellknotens erg�nzt durch die
     * Bedingung: n(c1) & n(c2) & ...
     * Die Bedingung wird vor dem Einf�gen vereinfacht. Falls die vereinfachte
     * Bedingung <code>false</code> ist, wird keine Kante eingef�gt.
     *
     * @param qKnotNam  Der Quellknoten, dessen Kanten erg�nzt werden
     *                  sollen.
     * @param zKnotNam  Der Zielknoten, zu dem die erg�nzende Kante
     *                  f�hren soll.
     * @param aut       Der zu ver�ndernde Automat.
     */
    private void addComplCond(
            final int qKnotNam,
            final int zKnotNam,
            final EndlicherAutomat aut) {
       
        int quellKnotNam = qKnotNam, zielKnotNam = zKnotNam;
        Knoten knot1;
        Knoten knot2;
        List<Transition> vorhTrans;
        List<Condition> vorhConds;
        Condition c;
        Condition[] cZwisch;
        ArrayList<Integer> knListe;
       
        /* Falls eine Kante zwischen den Knoten bereits existierte, erzeuge
         * eine Kante zwischen anderen (welchen?) Knoten... Zu �berpr�fen.
         */
        if (aut.holeKnoten(qKnotNam) != null
                && aut.holeKnoten(qKnotNam).getInfo() != null
                && aut.holeKnoten(qKnotNam).holeNachfolger().containsKey(
                        zielKnotNam)) {
            quellKnotNam = this.instrCounter;
            this.instrCounter++;
            zielKnotNam = this.instrCounter;
            this.instrCounter++;
           
            knListe = aut.getKnList();
            quellKnotNam = knListe.get(
                    SonstMeth.modZwischen(quellKnotNam, 0, knListe.size() - 1));
            zielKnotNam = knListe.get(
                    SonstMeth.modZwischen(zielKnotNam, 0, knListe.size() - 1));

            // Wenn immer noch eine Kante existiert, f�ge nichts ein.
            if (aut.holeKnoten(quellKnotNam) != null
                  && aut.holeKnoten(quellKnotNam).getInfo() != null
                  && aut.holeKnoten(quellKnotNam).holeNachfolger().containsKey(
                          zielKnotNam)) {
                SonstMeth.log(
                        SonstMeth.LOG_STAGE1,
                        "Erg�nzungskante nicht eingef�gt, da die ersten beiden"
                        + " Versuche bereits Kanten aufwiesen.",
                        this.pars);
                return;
            }
        }

        knot1 = aut.holeKnoten(quellKnotNam);
        knot2 = aut.holeKnoten(zielKnotNam);

        // F�ge Knoten neu ein, falls sie noch nicht existieren.
        if (knot1 == null) {
            this.insertNode(quellKnotNam, aut);
            knot1 = aut.holeKnoten(quellKnotNam);
        }
        if (knot2 == null) {
            this.insertNode(zielKnotNam, aut);
            knot2 = aut.holeKnoten(zielKnotNam);
        }

        if (knot1.getInfo() == null || knot1.getInfo().getBeds().size() == 0) {
            c = new ConstLeaf(true);
        } else {
            int i = 0;
            vorhTrans = knot1.getInfo().getBeds();
            vorhConds = new ArrayList<Condition>(vorhTrans.size());

            for (Transition t : vorhTrans) {
                vorhConds.add(t.getCond());
            }
           
            cZwisch = new Condition[vorhConds.size()];
           
            for (Condition condition : vorhConds) {
                cZwisch[i] = SonstMeth.ausFormatBed(condition.formatted());
                cZwisch[i].negiere();
                i++;
            }
           
            c = cZwisch[0];
            for (int j = 1; j < cZwisch.length; j++) {
                c = new InnerNode(
                        c,
                        cZwisch[j],
                        fmg.fmg8.endlAutomat.Konstanten.UND);
            }
        }
       
        c = c.simplify();
       
        // BO
//        System.out.println();
//        System.out.println(
//            aut.holeKnoten(quellKnotNam).getInfo().getBedingungen());
//        System.out.println(c);
//        c = c;
        // EO
       
        if (!c.equals(new ConstLeaf(false))) {
            aut.einfuegKante(
                    quellKnotNam,
                    zielKnotNam,
                    c,
                    1);
        }
    }
   
    /**
     * Executes the instruction on the specified automaton.
     *
     *     - k(x)   : Inserts node x.
     *     - b(x, y): Inserts node x if it does not exist; then changes the
     *                instruction of x to y.
     *     - p(x, y): Like b(x, y), but for parameter.
     *     - z(x, y): Like b(x, y), but for additional parameter.
     *     - T(x)   : Adds a token to the current condition. If the current
     *                condition is null, creates one.
     *     - K(x, y): Inserts transition from x to y with corrent Condition;
     *                Condition == null => Generate "false"
     *                if x or y do not exist, creates them; sets current
     *                Condition to null.
     *     - E(x, y): Inserts a transition from x to y completing all current
     *                transitions of x.
     *
     * @param aut   The automaton to be altered.
     * @param inst  The Instruction to be executed.
     */
    private void execute(final EndlicherAutomat  aut,
                         final ScriptInstruction inst) {
       
        int instName = this.normalize(inst.getInstName());
        int[] parameters = new int[inst.getInstParam().length];
       
        for (int i = 0; i < parameters.length; i++) {
            parameters[i] = this.normalize(inst.getInstParam()[i]);
        }
       
        if (inst.getInstName() == 0) { // Insert node.
            this.insertNode(parameters[0], aut);
           
        } else if (instName == 1
                   || instName == 2
                   || instName == 3) { // Change part of node.

            int mode = instName;
            int knotNam = parameters[0];
            int setValue = parameters[1];
           
            this.changeNode(mode, knotNam, setValue, aut);

        } else if (instName == 4) { // Insert transition.
            this.insertEdge(parameters[0],
                            parameters[1],
                            aut);
        } else if (instName == 5) { // Begin condition.
            this.addCondTok(inst.getInstParam()[0]);
        } else if (instName == 6) { // Insert completing transition.
            this.addComplCond(parameters[0], parameters[1], aut);
        }
    }
   
    /**
     * Generates an automaton based on the assigned Script.
     *
     * @param aut     The automaton to construct.
     * @param script  The script which the construction is based on.
     */
    public void generateAutomaton(
            final EndlicherAutomat aut,
            final Script           script) {
        Iterator<ScriptInstruction> it = script.iterator();
        ScriptInstruction inst;
        int knotNum1, knotNum2, knotNam1, knotNam2;
        LinkedList<Integer> autKnoten;
       
        SonstMeth.log(SonstMeth.LOG_STAGE1,
                      "Executing Script: "
                      + script.toString().replace('\n', ' '),
                      this.pars);

        this.reset();
        aut.leereGraph();

        while (it.hasNext()) {
            inst = it.next();
            this.execute(aut, inst);
           
            // BO
//            inst = inst;
//            System.out.println("\n" + inst);
//            System.out.println(aut.erzeugeSequenz().size());
            // EO
        }
       
        // Falls noch eine Bedingung wartet, eine neue Kante einf�gen.
        if (this.condWaiting) {
            autKnoten = new LinkedList<Integer>(
                    aut.getAdjazenzliste().keySet());
            knotNum1 = SonstMeth.modZwischen(
                    this.instrCounter,
                    0,
                    autKnoten.size());
           
            knotNum2 = SonstMeth.modZwischen(
                    this.paramCounter,
                    0,
                    autKnoten.size());
           
            if (knotNum1 > autKnoten.size() - 1) {
                knotNam1 = knotNum1;
                if (knotNam1 <= 0) {
                    knotNam1 = 255;
                }
            } else {
                knotNam1 = autKnoten.get(knotNum1);
            }

            if (knotNum2 > autKnoten.size() - 1) {
                knotNam2 = knotNum2;
                if (knotNam2 <= 0) {
                    knotNam2 = 255;
                }
            } else {
                knotNam2 = autKnoten.get(knotNum2);
            }

            this.insertEdge(
                    knotNam1,
                    knotNam2,
                    aut);
        }
       
        SonstMeth.log(SonstMeth.LOG_STAGE1,
                      "Script executed.",
                      this.pars);
       
        SonstMeth.log(SonstMeth.LOG_STAGE1,
                      "Generated "
                          + aut.getClass().getCanonicalName()
                          + ".",
//                          + aut,
                      this.pars);
    }
   
    /**
     * Test.
     *
     * @param args  Nichts.
     */
    public static void main(final String[] args) {
        String[] p = {"log", "-1"};
        Parametersatz pars = new Parametersatz(p);
        ScriptInterpreter interp
            = new ScriptInterpreter(pars, ScriptInterpreter.MODUS_VERHALTEN);
        EndlicherAutomat a = new EndlicherAutomat(null, interp);
        String str = "";
       
//        for (int j = 0; j < 1000; j++) {
//            str = str + (j % Const.BEF_PAR.length) + "," + j * (13 + j);
//           
//            if (Const.BEF_PAR[j % Const.BEF_PAR.length] == 2) {
//                str = str + "," + (j + 1);
//            }
//           
//            str = str + ";";
//        }
//       
        str = "5, 422; 5, 4; 5, 232; 5, 239; 5, 293; 5, 1; 5, 262; ";
        str += "5, 8; 4, 1, 2; 6, 1, 3; 5, 423; 4, 3, 4;";
        str += "6, 3, 2; 6, 2, 3; 1, 2, 3;";
       
        SonstMeth.log(SonstMeth.LOG_STAGE1, "Raw script: " + str, pars);
       
        Script s = new Script(str);
        interp.generateAutomaton(a, s);
       
        (new Zwischenablage()).copyToClipboard(a.erzeugeStringSeq());
    }

    /**
     * @return  Returns the modus.
     */
    public int getModus() {
        return this.modus;
    }

    /**
     * @param mod  The modus to set.
     */
    public void setModus(final int mod) {
        this.modus = mod;
        this.cond.setModus(mod);
    }
}
TOP

Related Classes of fmg.fmg8.endlAutomat.script.ScriptInterpreter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.