mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 15:26:52 -04:00
Merge branch 'optimizeThreads'
This commit is contained in:
commit
8d1b34cc5b
@ -78,4 +78,9 @@ public class BoolTableExpanded implements BoolTable {
|
|||||||
public ArrayList<Variable> getVars() {
|
public ArrayList<Variable> getVars() {
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int realSize() {
|
||||||
|
return e.realSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,11 @@ public interface BoolTable {
|
|||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
ThreeStateValue get(int i);
|
ThreeStateValue get(int i);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the real size of the bool table
|
||||||
|
*/
|
||||||
|
default int realSize() {
|
||||||
|
return size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ public class BuilderExpressionCreator {
|
|||||||
el = new ExpressionListenerOptimizeJK(el);
|
el = new ExpressionListenerOptimizeJK(el);
|
||||||
|
|
||||||
expressions.replayTo(el);
|
expressions.replayTo(el);
|
||||||
|
el.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
package de.neemann.digital.gui.components.table;
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
import de.neemann.digital.analyse.*;
|
import de.neemann.digital.analyse.*;
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
|
||||||
import de.neemann.digital.analyse.expression.ExpressionException;
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
import de.neemann.digital.analyse.expression.Variable;
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
import de.neemann.digital.analyse.expression.format.FormatterException;
|
import de.neemann.digital.analyse.expression.format.FormatterException;
|
||||||
@ -17,7 +16,9 @@ import de.neemann.digital.lang.Lang;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@ -29,8 +30,10 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public class ExpressionCreator {
|
public class ExpressionCreator {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionCreator.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ExpressionCreator.class);
|
||||||
private static final int MAX_INPUTS_ALLOWED = 12;
|
private static final int MAX_INPUTS_ALLOWED = 12;
|
||||||
|
private static final int COMPLEX_VAR_SIZE = 8;
|
||||||
|
|
||||||
private final TruthTable theTable;
|
private final TruthTable theTable;
|
||||||
|
private ProgressListener progressListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -52,36 +55,55 @@ public class ExpressionCreator {
|
|||||||
public void create(ExpressionListener listener) throws ExpressionException, FormatterException, AnalyseException {
|
public void create(ExpressionListener listener) throws ExpressionException, FormatterException, AnalyseException {
|
||||||
final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
|
final List<Variable> vars = Collections.unmodifiableList(theTable.getVars());
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if (theTable.getResultCount() > 100) {
|
if (theTable.getResultCount() >= 4 && vars.size() > COMPLEX_VAR_SIZE) {
|
||||||
|
LOGGER.debug("use parallel solvers");
|
||||||
ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
ExecutorService ex = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
ThreadSaveExpressionListener threadListener = new ThreadSaveExpressionListener(listener);
|
|
||||||
|
ArrayList<Job> jobs = new ArrayList<>();
|
||||||
for (int table = 0; table < theTable.getResultCount(); table++) {
|
for (int table = 0; table < theTable.getResultCount(); table++) {
|
||||||
final int t = table;
|
final ExpressionListenerStore l = new ExpressionListenerStore(null);
|
||||||
|
jobs.add(simplify(l, vars, theTable.getResultName(table), theTable.getResult(table))
|
||||||
|
.setStorage(l));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("jobs: " + jobs.size());
|
||||||
|
|
||||||
|
ArrayList<Job> orderedJobs = new ArrayList<>(jobs);
|
||||||
|
orderedJobs.sort(Comparator.comparingInt(job -> -job.getComplexity()));
|
||||||
|
|
||||||
|
for (Job j : orderedJobs) {
|
||||||
ex.submit(() -> {
|
ex.submit(() -> {
|
||||||
try {
|
try {
|
||||||
simplify(listener, vars, theTable.getResultName(t), theTable.getResult(t));
|
j.run();
|
||||||
} catch (ExpressionException | FormatterException | AnalyseException e) {
|
j.close();
|
||||||
|
} catch (ExpressionException | FormatterException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ex.shutdown();
|
ex.shutdown();
|
||||||
try {
|
try {
|
||||||
ex.awaitTermination(100, TimeUnit.HOURS);
|
ex.awaitTermination(100, TimeUnit.HOURS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
threadListener.close();
|
|
||||||
|
for (Job j : jobs)
|
||||||
|
j.getStorage().replayTo(listener);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (int table = 0; table < theTable.getResultCount(); table++)
|
for (int table = 0; table < theTable.getResultCount(); table++)
|
||||||
simplify(listener, vars, theTable.getResultName(table), theTable.getResult(table));
|
simplify(listener, vars, theTable.getResultName(table), theTable.getResult(table)).run();
|
||||||
listener.close();
|
|
||||||
}
|
}
|
||||||
|
listener.close();
|
||||||
time = System.currentTimeMillis() - time;
|
time = System.currentTimeMillis() - time;
|
||||||
LOGGER.debug("time: " + time / 1000.0 + " sec");
|
LOGGER.debug("time: " + time / 1000.0 + " sec");
|
||||||
|
if (progressListener != null)
|
||||||
|
progressListener.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void simplify(ExpressionListener listener, List<Variable> vars, String resultName, BoolTable boolTable) throws AnalyseException, ExpressionException, FormatterException {
|
private Job simplify(ExpressionListener listener, List<Variable> vars, String resultName, BoolTable boolTable) throws AnalyseException, ExpressionException {
|
||||||
List<Variable> localVars = vars;
|
List<Variable> localVars = vars;
|
||||||
if (vars.size() > 4) {
|
if (vars.size() > 4) {
|
||||||
TableReducer tr = new TableReducer(vars, boolTable);
|
TableReducer tr = new TableReducer(vars, boolTable);
|
||||||
@ -97,7 +119,7 @@ public class ExpressionCreator {
|
|||||||
|
|
||||||
listener = new CheckResultListener(listener, localVars, boolTable);
|
listener = new CheckResultListener(listener, localVars, boolTable);
|
||||||
|
|
||||||
getMinimizer(localVars.size()).minimize(localVars, boolTable, resultName, listener);
|
return new Job(localVars, boolTable, resultName, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MinimizerInterface getMinimizer(int size) {
|
private MinimizerInterface getMinimizer(int size) {
|
||||||
@ -108,22 +130,70 @@ public class ExpressionCreator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the progress listener to use
|
||||||
|
*
|
||||||
|
* @param progressListener the progress listener
|
||||||
|
* @return this for chained calls
|
||||||
|
*/
|
||||||
|
public ExpressionCreator setProgressListener(ProgressListener progressListener) {
|
||||||
|
this.progressListener = progressListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private final static class ThreadSaveExpressionListener implements ExpressionListener {
|
/**
|
||||||
|
* Listener used to monitor the progress
|
||||||
|
*/
|
||||||
|
public interface ProgressListener {
|
||||||
|
/**
|
||||||
|
* Called if a equation is calculated
|
||||||
|
*/
|
||||||
|
void oneCompleted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if all equations are calculated
|
||||||
|
*/
|
||||||
|
void complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class Job {
|
||||||
|
private final List<Variable> localVars;
|
||||||
|
private final BoolTable boolTable;
|
||||||
|
private final String resultName;
|
||||||
private final ExpressionListener listener;
|
private final ExpressionListener listener;
|
||||||
|
private ExpressionListenerStore storage;
|
||||||
|
|
||||||
private ThreadSaveExpressionListener(ExpressionListener listener) {
|
private Job(List<Variable> localVars, BoolTable boolTable, String resultName, ExpressionListener listener) {
|
||||||
|
this.localVars = localVars;
|
||||||
|
this.boolTable = boolTable;
|
||||||
|
this.resultName = resultName;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void run() throws ExpressionException, FormatterException {
|
||||||
public synchronized void resultFound(String name, Expression expression) throws FormatterException, ExpressionException {
|
LOGGER.debug("start job with complexity " + getComplexity());
|
||||||
listener.resultFound(name, expression);
|
long time = System.currentTimeMillis();
|
||||||
|
getMinimizer(localVars.size()).minimize(localVars, boolTable, resultName, listener);
|
||||||
|
LOGGER.debug("finished job with complexity " + getComplexity() + ": " + (System.currentTimeMillis() - time) / 1000 + "sec");
|
||||||
|
if (progressListener != null)
|
||||||
|
progressListener.oneCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private int getComplexity() {
|
||||||
public synchronized void close() throws FormatterException, ExpressionException {
|
return boolTable.realSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close() throws FormatterException, ExpressionException {
|
||||||
listener.close();
|
listener.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExpressionListenerStore getStorage() {
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Job setStorage(ExpressionListenerStore storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ public class ExpressionListenerStore implements ExpressionListener {
|
|||||||
|
|
||||||
for (Result r : results)
|
for (Result r : results)
|
||||||
listener.resultFound(r.name, r.expression.copy());
|
listener.resultFound(r.name, r.expression.copy());
|
||||||
listener.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Helmut Neemann.
|
||||||
|
* Use of this source code is governed by the GPL v3 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
|
import de.neemann.digital.lang.Lang;
|
||||||
|
import de.neemann.gui.Screen;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple progress dialog which is used by the {@link ExpressionCreator}
|
||||||
|
*/
|
||||||
|
public class ProgressDialog extends JDialog implements ExpressionCreator.ProgressListener {
|
||||||
|
private final JProgressBar bar;
|
||||||
|
private int prog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance
|
||||||
|
*
|
||||||
|
* @param tableDialog the table dialog
|
||||||
|
*/
|
||||||
|
public ProgressDialog(TableDialog tableDialog) {
|
||||||
|
super(tableDialog, false);
|
||||||
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
|
bar = new JProgressBar(0, tableDialog.getModel().getTable().getResultCount());
|
||||||
|
int b = Screen.getInstance().getFontSize();
|
||||||
|
bar.setBorder(BorderFactory.createEmptyBorder(b, b, b, b));
|
||||||
|
final JLabel label = new JLabel(Lang.get("msg_optimizationInProgress"));
|
||||||
|
label.setBorder(BorderFactory.createEmptyBorder(b, b, 0, b));
|
||||||
|
getContentPane().add(label, BorderLayout.NORTH);
|
||||||
|
getContentPane().add(bar, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(tableDialog);
|
||||||
|
SwingUtilities.invokeLater(() -> setVisible(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void oneCompleted() {
|
||||||
|
SwingUtilities.invokeLater(() -> bar.setValue(++prog));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete() {
|
||||||
|
SwingUtilities.invokeLater(this::dispose);
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.gui.components.table;
|
package de.neemann.digital.gui.components.table;
|
||||||
|
|
||||||
import de.neemann.digital.analyse.*;
|
import de.neemann.digital.analyse.AnalyseException;
|
||||||
|
import de.neemann.digital.analyse.ModelAnalyserInfo;
|
||||||
|
import de.neemann.digital.analyse.TruthTable;
|
||||||
|
import de.neemann.digital.analyse.TruthTableTableModel;
|
||||||
import de.neemann.digital.analyse.expression.Expression;
|
import de.neemann.digital.analyse.expression.Expression;
|
||||||
import de.neemann.digital.analyse.expression.ExpressionException;
|
import de.neemann.digital.analyse.expression.ExpressionException;
|
||||||
import de.neemann.digital.analyse.expression.Variable;
|
import de.neemann.digital.analyse.expression.Variable;
|
||||||
@ -41,6 +44,8 @@ import de.neemann.gui.ErrorMessage;
|
|||||||
import de.neemann.gui.MyFileChooser;
|
import de.neemann.gui.MyFileChooser;
|
||||||
import de.neemann.gui.Screen;
|
import de.neemann.gui.Screen;
|
||||||
import de.neemann.gui.ToolTipAction;
|
import de.neemann.gui.ToolTipAction;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.TableModelEvent;
|
import javax.swing.event.TableModelEvent;
|
||||||
@ -61,8 +66,10 @@ import java.util.StringTokenizer;
|
|||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class TableDialog extends JDialog {
|
public class TableDialog extends JDialog {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TableDialog.class);
|
||||||
private static final Preferences PREFS = Preferences.userRoot().node("dig").node("generator");
|
private static final Preferences PREFS = Preferences.userRoot().node("dig").node("generator");
|
||||||
private static final Color MYGRAY = new Color(230, 230, 230);
|
private static final Color MYGRAY = new Color(230, 230, 230);
|
||||||
private static final List<Key> LIST = new ArrayList<>();
|
private static final List<Key> LIST = new ArrayList<>();
|
||||||
@ -304,6 +311,7 @@ public class TableDialog extends JDialog {
|
|||||||
if (createJK.isSelected())
|
if (createJK.isSelected())
|
||||||
expressionListener = new ExpressionListenerJK(expressionListener);
|
expressionListener = new ExpressionListenerJK(expressionListener);
|
||||||
lastGeneratedExpressions.replayTo(expressionListener);
|
lastGeneratedExpressions.replayTo(expressionListener);
|
||||||
|
expressionListener.close();
|
||||||
} catch (ExpressionException | FormatterException e1) {
|
} catch (ExpressionException | FormatterException e1) {
|
||||||
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show(TableDialog.this);
|
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show(TableDialog.this);
|
||||||
}
|
}
|
||||||
@ -584,16 +592,50 @@ public class TableDialog extends JDialog {
|
|||||||
|
|
||||||
private void calculateExpressions() {
|
private void calculateExpressions() {
|
||||||
try {
|
try {
|
||||||
|
LOGGER.info("start optimization");
|
||||||
ExpressionListener expressionListener = new HTMLExpressionListener();
|
ExpressionListener expressionListener = new HTMLExpressionListener();
|
||||||
|
|
||||||
if (createJK.isSelected())
|
if (createJK.isSelected())
|
||||||
expressionListener = new ExpressionListenerJK(expressionListener);
|
expressionListener = new ExpressionListenerJK(expressionListener);
|
||||||
|
|
||||||
|
final TruthTable table = model.getTable();
|
||||||
|
if (table.getVars().size() >= 8) {
|
||||||
|
ProgressDialog progress = new ProgressDialog(this);
|
||||||
|
|
||||||
|
ExpressionListener finalExpressionListener = expressionListener;
|
||||||
|
new Thread(() -> {
|
||||||
|
ExpressionListenerStore storage = new ExpressionListenerStore(null);
|
||||||
|
try {
|
||||||
|
new ExpressionCreator(table).setProgressListener(progress).create(storage);
|
||||||
|
} catch (ExpressionException | FormatterException | AnalyseException e) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
progress.dispose();
|
||||||
|
lastGeneratedExpressions = null;
|
||||||
|
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e).show(this);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
lastGeneratedExpressions = new ExpressionListenerStore(finalExpressionListener);
|
||||||
|
storage.replayTo(lastGeneratedExpressions);
|
||||||
|
lastGeneratedExpressions.close();
|
||||||
|
kvMap.setResult(table, lastGeneratedExpressions.getResults());
|
||||||
|
} catch (FormatterException | ExpressionException e) {
|
||||||
|
lastGeneratedExpressions = null;
|
||||||
|
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e).show(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}).start();
|
||||||
|
} else {
|
||||||
lastGeneratedExpressions = new ExpressionListenerStore(expressionListener);
|
lastGeneratedExpressions = new ExpressionListenerStore(expressionListener);
|
||||||
new ExpressionCreator(model.getTable()).create(lastGeneratedExpressions);
|
new ExpressionCreator(table).create(lastGeneratedExpressions);
|
||||||
|
kvMap.setResult(table, lastGeneratedExpressions.getResults());
|
||||||
kvMap.setResult(model.getTable(), lastGeneratedExpressions.getResults());
|
}
|
||||||
|
|
||||||
|
LOGGER.info("optimization finished");
|
||||||
} catch (ExpressionException | FormatterException | AnalyseException e1) {
|
} catch (ExpressionException | FormatterException | AnalyseException e1) {
|
||||||
lastGeneratedExpressions = null;
|
lastGeneratedExpressions = null;
|
||||||
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show(this);
|
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e1).show(this);
|
||||||
@ -731,6 +773,7 @@ public class TableDialog extends JDialog {
|
|||||||
public void close() {
|
public void close() {
|
||||||
html.append("</table></html>");
|
html.append("</table></html>");
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 0:
|
case 0:
|
||||||
statusBar.setVisible(false);
|
statusBar.setVisible(false);
|
||||||
@ -745,8 +788,9 @@ public class TableDialog extends JDialog {
|
|||||||
statusBar.setVisible(false);
|
statusBar.setVisible(false);
|
||||||
allSolutionsDialog.setText(html.toString());
|
allSolutionsDialog.setText(html.toString());
|
||||||
if (!allSolutionsDialog.isVisible())
|
if (!allSolutionsDialog.isVisible())
|
||||||
SwingUtilities.invokeLater(() -> allSolutionsDialog.setVisible(true));
|
allSolutionsDialog.setVisible(true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,6 +918,7 @@ Es sind nur {1} Variablen erlaubt, es wurden jedoch {2} gefunden.</string>
|
|||||||
<string name="err_processExitedWithError_N1_N2">Der Prozess meldet den Rückgabewert {0}: {1}</string>
|
<string name="err_processExitedWithError_N1_N2">Der Prozess meldet den Rückgabewert {0}: {1}</string>
|
||||||
<string name="err_errorRunningFitter">Fehler beim Starten des externen Fitters!</string>
|
<string name="err_errorRunningFitter">Fehler beim Starten des externen Fitters!</string>
|
||||||
<string name="err_noExpressionsAvailable">Es liegen keine minimierten Gleichungen vor!</string>
|
<string name="err_noExpressionsAvailable">Es liegen keine minimierten Gleichungen vor!</string>
|
||||||
|
<string name="msg_optimizationInProgress">Gleichungen werden berechnet! Einen Moment Geduld!</string>
|
||||||
<string name="err_varName_N_UsedTwice">Die Variable {0} wird mehrfach verwendet!</string>
|
<string name="err_varName_N_UsedTwice">Die Variable {0} wird mehrfach verwendet!</string>
|
||||||
<string name="err_fileNeedsToBeSaved">Die Datei muss zunächst gespeichert werden!</string>
|
<string name="err_fileNeedsToBeSaved">Die Datei muss zunächst gespeichert werden!</string>
|
||||||
<string name="err_recursiveNestingAt_N0">Die Schaltung {0} bindet sich selbst ein!</string>
|
<string name="err_recursiveNestingAt_N0">Die Schaltung {0} bindet sich selbst ein!</string>
|
||||||
|
@ -912,6 +912,7 @@
|
|||||||
<string name="err_processExitedWithError_N1_N2">The process returns the non zero value {0}: {1}</string>
|
<string name="err_processExitedWithError_N1_N2">The process returns the non zero value {0}: {1}</string>
|
||||||
<string name="err_errorRunningFitter">Error starting the external fitter!</string>
|
<string name="err_errorRunningFitter">Error starting the external fitter!</string>
|
||||||
<string name="err_noExpressionsAvailable">There are no minimized equations!</string>
|
<string name="err_noExpressionsAvailable">There are no minimized equations!</string>
|
||||||
|
<string name="msg_optimizationInProgress">Equations are calculated! Please wait a moment!</string>
|
||||||
<string name="err_varName_N_UsedTwice">The variable {0} is used twice!</string>
|
<string name="err_varName_N_UsedTwice">The variable {0} is used twice!</string>
|
||||||
<string name="err_fileNeedsToBeSaved">The file needs to be saved!</string>
|
<string name="err_fileNeedsToBeSaved">The file needs to be saved!</string>
|
||||||
<string name="err_recursiveNestingAt_N0">The circuit {0} imports itself!</string>
|
<string name="err_recursiveNestingAt_N0">The circuit {0} imports itself!</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user