mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 07:48:29 -04:00
added truth table generation
This commit is contained in:
parent
a0c134b01d
commit
ec1511258d
@ -5,11 +5,15 @@
|
||||
*/
|
||||
package de.neemann.digital.fsm;
|
||||
|
||||
import de.neemann.digital.analyse.expression.Expression;
|
||||
import de.neemann.digital.analyse.TruthTable;
|
||||
import de.neemann.digital.analyse.expression.*;
|
||||
import de.neemann.digital.draw.graphics.Graphic;
|
||||
import de.neemann.digital.draw.graphics.VectorFloat;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* A simple finite state machine
|
||||
@ -165,4 +169,122 @@ public class FSM {
|
||||
for (Transition t : transitions)
|
||||
t.initPos();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the truth table which is defined by this finite state machine
|
||||
*
|
||||
* @return the truth table
|
||||
* @throws ExpressionException ExpressionException
|
||||
* @throws FinitStateMachineException FinitStateMachineException
|
||||
*/
|
||||
public TruthTable createTruthTable() throws ExpressionException, FinitStateMachineException {
|
||||
int stateBits = getStateVarBits();
|
||||
|
||||
// create state variables
|
||||
ArrayList<Variable> vars = new ArrayList<>();
|
||||
for (int i = stateBits - 1; i >= 0; i--)
|
||||
vars.add(new Variable("Q^" + i + "_n"));
|
||||
|
||||
TruthTable truthTable = new TruthTable(vars);
|
||||
|
||||
// create the next state result variables
|
||||
for (int i = stateBits - 1; i >= 0; i--)
|
||||
truthTable.addResult("Q^" + i + "_n+1");
|
||||
|
||||
// add the output variables
|
||||
TreeSet<String> results = new TreeSet<>();
|
||||
for (State s : states)
|
||||
results.addAll(s.getValues().keySet());
|
||||
|
||||
for (String name : results)
|
||||
truthTable.addResult(name);
|
||||
|
||||
// set all to dc
|
||||
truthTable.setAllTo(2);
|
||||
|
||||
// set output variables
|
||||
for (State s : states) {
|
||||
int row = s.getNumber();
|
||||
int col = stateBits * 2;
|
||||
for (String name : results) {
|
||||
Long val = s.getValues().get(name);
|
||||
long v = val == null ? 0 : val;
|
||||
truthTable.setValue(row, col, (int) v);
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set all next state variables to "stay is state"
|
||||
for (State s : states) {
|
||||
int c = stateBits * 2;
|
||||
int row = s.getNumber();
|
||||
int m = row;
|
||||
for (int j = 0; j < stateBits; j++) {
|
||||
c--;
|
||||
truthTable.setValue(row, c, m & 1);
|
||||
m >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// add the additional input variables
|
||||
VariableVisitor vv = new VariableVisitor();
|
||||
for (Transition t : transitions)
|
||||
if (t.getCondition() != null)
|
||||
t.getCondition().traverse(vv);
|
||||
ArrayList<Variable> inVars = new ArrayList<>(vv.getVariables());
|
||||
|
||||
for (Variable v : inVars)
|
||||
truthTable.addVariable(v);
|
||||
|
||||
int rowsPerState = 1 << inVars.size();
|
||||
|
||||
// fill in the transitions
|
||||
for (Transition t : transitions) {
|
||||
int startState = t.getStartState().getNumber();
|
||||
int startRow = startState * rowsPerState;
|
||||
ContextMap c = new ContextMap();
|
||||
for (int r = 0; r < rowsPerState; r++) {
|
||||
int m = 1 << (inVars.size() - 1);
|
||||
for (Variable v : inVars) {
|
||||
c.set(v, (r & m) != 0);
|
||||
m >>= 1;
|
||||
}
|
||||
if (t.getCondition() == null || t.getCondition().calculate(c)) {
|
||||
int col = stateBits * 2 + inVars.size();
|
||||
int row = startRow + r;
|
||||
int mask = t.getTargetState().getNumber();
|
||||
for (int j = 0; j < stateBits; j++) {
|
||||
col--;
|
||||
truthTable.setValue(row, col, mask & 1);
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return truthTable;
|
||||
|
||||
}
|
||||
|
||||
private int getStateVarBits() throws FinitStateMachineException {
|
||||
HashSet<Integer> numbers = new HashSet<>();
|
||||
int maxNumber = 0;
|
||||
for (State s : states) {
|
||||
final int n = s.getNumber();
|
||||
if (n > maxNumber)
|
||||
maxNumber = n;
|
||||
|
||||
if (numbers.contains(n))
|
||||
throw new FinitStateMachineException(Lang.get("err_fsmNumberUsedTwice_N", n));
|
||||
numbers.add(n);
|
||||
}
|
||||
|
||||
if (!numbers.contains(0))
|
||||
throw new FinitStateMachineException(Lang.get("err_fsmNoInitialState"));
|
||||
|
||||
int n = 1;
|
||||
while ((1 << n) <= maxNumber) n++;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
@ -124,4 +124,11 @@ public class State extends Movable {
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the state value map
|
||||
*/
|
||||
public TreeMap<String, Long> getValues() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
@ -121,4 +121,25 @@ public class Transition extends Movable {
|
||||
setPos(fromState.getPos().add(toState.getPos()).mul(0.5f)
|
||||
.add(new VectorFloat((float) Math.random() - 0.5f, (float) Math.random() - 0.5f).mul(30)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the condition
|
||||
*/
|
||||
public Expression getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the starting state
|
||||
*/
|
||||
public State getStartState() {
|
||||
return fromState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the target state
|
||||
*/
|
||||
public State getTargetState() {
|
||||
return toState;
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ package de.neemann.digital.fsm.gui;
|
||||
import de.neemann.digital.analyse.expression.Expression;
|
||||
import de.neemann.digital.analyse.parser.ParseException;
|
||||
import de.neemann.digital.analyse.parser.Parser;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||
import de.neemann.digital.fsm.FSM;
|
||||
import de.neemann.digital.fsm.State;
|
||||
import de.neemann.digital.gui.components.table.TableDialog;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -38,7 +41,6 @@ public class FSMDialog extends JDialog {
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
this.fsm = fsm;
|
||||
|
||||
|
||||
fsmComponent = new FSMComponent(fsm);
|
||||
getContentPane().add(fsmComponent);
|
||||
pack();
|
||||
@ -72,49 +74,43 @@ public class FSMDialog extends JDialog {
|
||||
* @throws Exception Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
FSM fsm = new FSM()
|
||||
.add(new State("initial").val("Y", 0))
|
||||
.add(new State("1 match").val("Y", 0))
|
||||
.add(new State("2 matches").val("Y", 0))
|
||||
.add(new State("found").val("Y", 1))
|
||||
.transition(0, 1, new Parser("!E").parse().get(0))
|
||||
.transition(1, 2, new Parser("!E").parse().get(0))
|
||||
.transition(2, 3, new Parser("E").parse().get(0))
|
||||
|
||||
.transition(1, 0, new Parser("E").parse().get(0))
|
||||
.transition(3, 0, new Parser("E").parse().get(0))
|
||||
.transition(3, 1, new Parser("!E").parse().get(0));*/
|
||||
|
||||
State top = new State("top");
|
||||
State topSet = new State("topSet").val("Y", 1);
|
||||
State topSetLeft = new State("topSetLeft").val("L", 1);
|
||||
State topSetRight = new State("topSetRight").val("R", 1);
|
||||
State leftA = new State("leftA");
|
||||
State leftB = new State("leftB");
|
||||
State bottom = new State("bottom");
|
||||
State bottomSet = new State("bottomSet").val("Y", 1);
|
||||
State bottomSetLeft = new State("bottomSetRight").val("R", 1);
|
||||
State bottomSetRight = new State("bottomSetLeft").val("L", 1);
|
||||
State rightA = new State("rightA");
|
||||
State rightB = new State("rightB");
|
||||
FSM fsm = new FSM(top, topSet, leftA, leftB, bottom, bottomSet, rightA, rightB)
|
||||
FSM fsm = new FSM(top, topSetLeft, leftA, leftB, bottomSetLeft, bottom, bottomSetRight, rightB, rightA, topSetRight)
|
||||
.transition(top, leftA, e("A & !B"))
|
||||
.transition(top, rightA, e("!A & B"))
|
||||
.transition(topSet, top, null)
|
||||
.transition(topSetLeft, top, null)
|
||||
.transition(topSetRight, top, null)
|
||||
|
||||
.transition(rightA, top, e("!A & !B"))
|
||||
.transition(rightB, topSet, e("!A & !B"))
|
||||
.transition(rightB, topSetRight, e("!A & !B"))
|
||||
.transition(leftA, top, e("!A & !B"))
|
||||
.transition(leftB, topSet, e("!A & !B"))
|
||||
.transition(leftB, topSetLeft, e("!A & !B"))
|
||||
|
||||
.transition(bottom, leftB, e("A & !B"))
|
||||
.transition(bottom, rightB, e("!A & B"))
|
||||
.transition(bottomSet, bottom, null)
|
||||
.transition(bottomSetLeft, bottom, null)
|
||||
.transition(bottomSetRight, bottom, null)
|
||||
|
||||
.transition(rightB, bottom, e("A & B"))
|
||||
.transition(rightA, bottomSet, e("A & B"))
|
||||
.transition(rightA, bottomSetRight, e("A & B"))
|
||||
.transition(leftB, bottom, e("A & B"))
|
||||
.transition(leftA, bottomSet, e("A & B"));
|
||||
.transition(leftA, bottomSetLeft, e("A & B"));
|
||||
|
||||
|
||||
new FSMDialog(null, fsm).setVisible(true);
|
||||
ElementLibrary lib = new ElementLibrary();
|
||||
ShapeFactory shapeFactory = new ShapeFactory(lib);
|
||||
new TableDialog(null, fsm.createTruthTable(), lib, shapeFactory, null).setVisible(true);
|
||||
|
||||
//new FSMDialog(null, fsm).setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user