All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xcsp.common.structures.Automaton Maven / Gradle / Ivy

Go to download

Java Tools for parsing XCSP3 instances, compiling JvCSP3 models, and checking solutions. For more information about XCSP3, follow www.xcsp.org

The newest version!
/**
 * AbsCon - Copyright (c) 2017, CRIL-CNRS - [email protected]
 * 
 * All rights reserved.
 * 
 * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this
 * distribution, and is available at http://www.cecill.info
 */
package org.xcsp.common.structures;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.xcsp.common.Utilities;

/**
 * This class allows us to represent finite automatons that are useful for posting {@code regular} constraints. An
 * automaton is composed of an initial state, a finite set of final states and a finite set of transitions.
 */
public final class Automaton {
	/**
	 * The start (initial) state of the automaton.
	 */
	public final String startState;

	/**
	 * The set (array) of transitions. Each transition is an object composed of a first state, a symbol (that may be an
	 * integer or a string) and a second state that is reached from the first state after reading the symbol.
	 */
	public final Transition[] transitions;

	/**
	 * The set (array) of final states of the automaton, i.e., accepting stated of the automaton.
	 */
	public final String[] finalStates;

	/**
	 * Cache used for storing the fact that the automaton is deterministic or not
	 */
	private Boolean deterministic;

	/**
	 * Constructs an automaton from the specified arguments.
	 * 
	 * @param startState
	 *            the start state of the automaton
	 * @param transitions
	 *            the set (array) of transitions where each transition is an object composed of a first state, a symbol
	 *            (that may be an integer or a string) and a second state that is reached from the first state after
	 *            reading the symbol
	 * @param finalStates
	 *            the set (array) of final states of the automaton, i.e., accepting stated of the automaton
	 */
	public Automaton(String startState, Transition[] transitions, String... finalStates) {
		this.startState = startState;
		this.transitions = transitions;
		this.finalStates = finalStates;
	}

	/**
	 * Constructs an automaton from the specified arguments.
	 * 
	 * @param startState
	 *            the start state of the automaton
	 * @param transitions
	 *            the object encapsulating the list of transitions where each transition is an object composed of a
	 *            first state, a symbol (that may be an integer or a string) and a second state that is reached from the
	 *            first state after reading the symbol
	 * @param finalStates
	 *            the set (array) of final states of the automaton, i.e., accepting stated of the automaton
	 */
	public Automaton(String startState, Transitions transitions, String... finalStates) {
		this(startState, transitions.toArray(), finalStates);
	}

	/**
	 * Constructs an automaton from the specified regular expression, given as a string.
	 * 
	 * @param expression
	 *            the expression representing a regular expression.
	 */
	public Automaton(String expression) {
		Utilities.exit("Unimplemented code; converting regular expressions into an automaton");
		this.startState = null;
		this.transitions = null;
		this.finalStates = null;
	}

	public boolean _isDeterministic() {
		Set encountered = new HashSet<>();
		for (Transition tr : transitions)
			if (tr.value instanceof int[]) {
				for (int v : (int[]) tr.value) {
					if (encountered.contains(tr.start + " " + v))
						return false;
					encountered.add(tr.start + " " + v);
				}
			} else {
				if (encountered.contains(tr.start + " " + tr.value))
					return false;
				encountered.add(tr.start + " " + tr.value);
			}
		return true;
	}

	public boolean isDeterministic() {
		if (deterministic == null)
			deterministic = _isDeterministic();
		return deterministic;
	}

	@Override
	public String toString() {
		return "startState=" + startState + " finalStates={" + Utilities.join(finalStates) + "} " + "\ntransitions={"
				+ Stream.of(transitions).map(t -> t.toString()).collect(Collectors.joining()) + "}";
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy