/* * Copyright (C) 2020 Matthias Heizmann (heizmann@informatik.uni-freiburg.de) * Copyright (C) 2020 University of Freiburg * * This file is part of the ULTIMATE Automata Library. * * The ULTIMATE Automata Library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ULTIMATE Automata Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ULTIMATE Automata Library. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify the ULTIMATE Automata Library, or any covered work, by linking * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), * containing parts covered by the terms of the Eclipse Public License, the * licensors of the ULTIMATE Automata Library grant you additional permission * to convey the resulting work. */ package de.uni_freiburg.informatik.ultimate.automata.counting; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryException; import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryServices; import de.uni_freiburg.informatik.ultimate.automata.IOperation; import de.uni_freiburg.informatik.ultimate.automata.statefactory.IIntersectionStateFactory; import de.uni_freiburg.informatik.ultimate.automata.statefactory.IStateFactory; import de.uni_freiburg.informatik.ultimate.core.model.services.ILogger; /** * Concatenation method for Counting Automata * * @author Marcel Ebbinghaus * @author who is the author? */ public class Concatenation> implements IOperation { private final AutomataLibraryServices mServices; private final ILogger mLogger; private final CountingAutomaton mFstOperand; private final CountingAutomaton mSndOperand; private final CountingAutomaton mResult; private final IIntersectionStateFactory mStateFactory; public Concatenation( final AutomataLibraryServices services, final IIntersectionStateFactory stateFactory, final CountingAutomaton fstOperand, final CountingAutomaton sndOperand) throws AutomataLibraryException { mServices = services; mLogger = mServices.getLoggingService().getLogger(this.getClass()); mFstOperand = fstOperand; mSndOperand = sndOperand; mStateFactory = stateFactory; if (mLogger.isInfoEnabled()) { mLogger.info(startMessage()); } mResult = computeResult(); if (mLogger.isInfoEnabled()) { mLogger.info(exitMessage()); } } private CountingAutomaton computeResult() { Set concatenationAlphabet = new HashSet(); concatenationAlphabet.addAll(mFstOperand.getAlphabet()); ArrayList concatenationCounter = new ArrayList(); for (Counter counter : mFstOperand.getCounter()) { concatenationCounter.add(counter.copyCounter()); } for (Counter counter : mSndOperand.getCounter()) { concatenationCounter.add(counter.copyCounter()); } Set concatenationStates = new HashSet(); concatenationStates.addAll(mFstOperand.getStates()); concatenationStates.addAll(mSndOperand.getStates()); Map concatenationInitialConditions = new HashMap(); Map concatenationFinalConditions = new HashMap(); Map>> concatenationTransitions = new HashMap>>(); //initialize parameters of fstOperand for (STATE state : mFstOperand.getStates()) { concatenationInitialConditions.put(state, mFstOperand.getInitialConditions().get(state).copyInitialCondition()); concatenationFinalConditions.put(state, mFstOperand.getFinalConditions().get(state).copyFinalCondition()); ArrayList> transitionList = new ArrayList>(); for (Transition transition : mFstOperand.getTransitions().get(state)) { transitionList.add(transition.copyTransition()); } concatenationTransitions.put(state, transitionList); } //initialize parameters of SndOperand for (STATE state : mSndOperand.getStates()) { Guard newGuardFalse = new Guard(); newGuardFalse.changeTermType(TermType.FALSE); ArrayList guardListFalse = new ArrayList(); guardListFalse.add(newGuardFalse); ArrayList> newInitialConditionList = new ArrayList>(); newInitialConditionList.add(guardListFalse); InitialCondition newInitialCondition = new InitialCondition(newInitialConditionList); concatenationInitialConditions.put(state, newInitialCondition); concatenationFinalConditions.put(state, mSndOperand.getFinalConditions().get(state).copyFinalCondition()); ArrayList> transitionList = new ArrayList>(); for (Transition transition : mSndOperand.getTransitions().get(state)) { transitionList.add(transition.copyTransition()); } concatenationTransitions.put(state, transitionList); } //connect finalStates of mFstOperand with initialStates of mSndOperand for (STATE stateFstOp : mFstOperand.getStates()) { if (mFstOperand.getFinalConditions().get(stateFstOp).getCondition().get(0).get(0).getTermType() != TermType.FALSE) { ArrayList> newTransitions = new ArrayList>(); for (Transition transition : concatenationTransitions.get(stateFstOp)) newTransitions.add(transition); ArrayList> newFinalConditionsList = new ArrayList>(); for (STATE stateSndOp : mSndOperand.getStates()) { if (mSndOperand.getInitialConditions().get(stateSndOp).getCondition().get(0).get(0).getTermType() != TermType.FALSE) { //add new transitions for (Transition transition : mSndOperand.getTransitions().get(stateSndOp)) { Transition transitionCopy = transition.copyTransition(); ConjunctGuards conjunction1 = new ConjunctGuards( transitionCopy.getGuards(), mFstOperand.getFinalConditions().get(stateFstOp).copyFinalCondition().getCondition()); ConjunctGuards conjunction2 = new ConjunctGuards( conjunction1.getResult(), mSndOperand.getInitialConditions().get(stateSndOp).copyInitialCondition().getCondition()); Transition newTransition = new Transition(transitionCopy.getLetter(), stateFstOp, transitionCopy.getSucState(), conjunction2.getResult(), transitionCopy.getUpdates()); newTransitions.add(newTransition); } //add finalCondition if stateSndOp is final as well if (mSndOperand.getFinalConditions().get(stateSndOp).getCondition().get(0).get(0).getTermType() != TermType.FALSE) { ConjunctGuards conjunction1 = new ConjunctGuards( mFstOperand.getFinalConditions().get(stateFstOp).copyFinalCondition().getCondition(), mSndOperand.getInitialConditions().get(stateSndOp).copyInitialCondition().getCondition()); ConjunctGuards conjunction2 = new ConjunctGuards( conjunction1.getResult(), mSndOperand.getFinalConditions().get(stateSndOp).copyFinalCondition().getCondition()); newFinalConditionsList.addAll(conjunction2.getResult()); } } } concatenationTransitions.put(stateFstOp, newTransitions); //construct finalCondition == false, if there were no states in mSndOperand which are initial and final at once if (newFinalConditionsList.size() == 0) { Guard newGuardFalse = new Guard(); newGuardFalse.changeTermType(TermType.FALSE); ArrayList guardListFalse = new ArrayList(); guardListFalse.add(newGuardFalse); newFinalConditionsList.add(guardListFalse); } FinalCondition newFinalCondition = new FinalCondition(newFinalConditionsList); concatenationFinalConditions.put(stateFstOp, newFinalCondition); } } //result CountingAutomaton resultAutomaton = new CountingAutomaton( mServices, concatenationAlphabet, concatenationStates, concatenationCounter, concatenationInitialConditions, concatenationFinalConditions, concatenationTransitions); return resultAutomaton; } @Override public CountingAutomaton getResult() { return mResult; } @Override public boolean checkResult(CRSF stateFactory) throws AutomataLibraryException { // TODO: Check the result return true; } }