Skip to content
Snippets Groups Projects
  • Tomáš Pecka's avatar
    b9be7075
    aconversion: changes (see details) · b9be7075
    Tomáš Pecka authored
     - FA -> LRG: fix double addition of rules
     - Glushkov: use different state/nonterminal names. Names are generated via hexavigesimal with symbol id appended
     - Thompson: use different state names
     - Brzozowski: fix numbering - start at 0 so hexavigesimal starts properly at A
     - RRG -> FA: if createUnique is used, then use A' instead of A0
    
     - tests: correct exit values to determine if process reached timeout or segfault
    b9be7075
    History
    aconversion: changes (see details)
    Tomáš Pecka authored
     - FA -> LRG: fix double addition of rules
     - Glushkov: use different state/nonterminal names. Names are generated via hexavigesimal with symbol id appended
     - Thompson: use different state names
     - Brzozowski: fix numbering - start at 0 so hexavigesimal starts properly at A
     - RRG -> FA: if createUnique is used, then use A' instead of A0
    
     - tests: correct exit values to determine if process reached timeout or segfault
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tests.aconversion.sh 5.21 KiB
#!/usr/bin/env bash

set -o pipefail

TESTCASE_ITERATIONS=100
TESTCASE_TIMEOUT=5
LOGFILE="log_tests.txt"

RAND_STATES=18
RAND_DENSITY="2.5"
RAND_ALPHABET=4

EXECUTABLES="arand aepsilon atrim adeterminize aminimize anormalize adiff.automaton aconversion"

TESTS_DIR="../examples/automaton"

# ----------------------------

for FILE in $EXECUTABLES; do
	if [ ! -f bin/$FILE ]; then
		echo "Executable" $FILE "is required for testing. Make sure it is in bin folder."
		exit 1
	fi
done

cd bin/
rm -f $LOGFILE

# ----------------------------

function mDFA {
	echo "$1" | ./aepsilon | ./atrim | ./adeterminize -t FSM | ./aminimize | ./anormalize
}

function compare {
	echo "$1" > tmp1.xml
	echo "$2" > tmp2.xml

	# relies on ret code by adiff.automaton
	./adiff.automaton tmp1.xml tmp2.xml
	RET=$?
	rm tmp1.xml tmp2.xml

	return $RET
}

function generateNFA {
	./arand -d $RAND_DENSITY -n $(( $RANDOM % $RAND_STATES + 1 )) -a $(( $RANDOM % $RAND_ALPHABET + 1 )) 2>/dev/null
}

# $1 = command for conversion. Output of such command must be (eps-)NFA !!
# $2 = automaton
function runTest2 {
	TMPNFA="nfa.xml"
	echo "$2" > $TMPNFA

	TMP=$(timeout $TESTCASE_TIMEOUT bash -c "cat $TMPNFA | $1" 2>/dev/null)
	RETTMP=$?

	# segfault
	if [ $RETTMP -eq 134 ]; then
		return 3
	fi

	# timeout
	if [ $RETTMP -ge 123 ]; then
		return 2
	fi

	mDFA1=$(mDFA "$(cat $TMPNFA)")
	mDFA2=$(mDFA "$TMP")

	# as pipefail bash option is turned on, first non-zero exit value of any program in pipe sequence is return code of whole sequence
	CMP=$(compare "$mDFA1" "$mDFA2")
	if [ $? == 0 ]; then
		rm $TMPNFA
		return 0
	else
		echo "-----------------------------------------" >> $LOGFILE
		echo "$1" >> $LOGFILE
		echo "$CMP" >> $LOGFILE
		echo $(cat $TMPNFA) >> $LOGFILE
		rm $TMPNFA
		return 1
	fi
}

# $1 - aconversion sequence
function runTest {
	RES_GOOD=0
	RES_FAIL=0
	RES_TIMEOUT=0
	RES_SIGSEGV=0

	echo $1
	echo -ne "\t"

	# predefined tests first
	for FILE in `ls $TESTS_DIR/aconversion.test*`; do
		AUTOMATON=$(cat $FILE)

		runTest2 "$1" "$AUTOMATON"
		TEST_EXITVALUE=$?

		if [ $TEST_EXITVALUE == 0 ]; then
			echo -n "."
			RES_GOOD=$((RES_GOOD + 1))
		elif [ $TEST_EXITVALUE == 1 ]; then
			echo -n "x"
			RES_FAIL=$((RES_FAIL + 1))
		elif [ $TEST_EXITVALUE == 2 ]; then
			echo -n "T"
			RES_TIMEOUT=$((RES_TIMEOUT + 1))
		elif [ $TEST_EXITVALUE == 3 ]; then
			echo -n "F"
			RES_SIGSEGV=$((RES_SIGSEGV + 1))
		else
			echo -n "?"
		fi
	done

	echo -n " | "

	# random tests
	for i in $(seq 1 $TESTCASE_ITERATIONS );
	do
		RAND_AUTOMATON=$(generateNFA)
		if [ $? -eq 139 ]; then
			echo -n "F"
			RES_SIGSEGV=$((RES_SIGSEGV + 1))
			continue
		fi

		runTest2 "$1" "$RAND_AUTOMATON"
		TEST_EXITVALUE=$?

		if [ $TEST_EXITVALUE == 0 ]; then
			echo -n "."
			RES_GOOD=$((RES_GOOD + 1))
		elif [ $TEST_EXITVALUE == 1 ]; then
			echo -n "x"
			RES_FAIL=$((RES_FAIL + 1))
		elif [ $TEST_EXITVALUE == 2 ]; then
			echo -n "T"
			RES_TIMEOUT=$((RES_TIMEOUT + 1))
		elif [ $TEST_EXITVALUE == 3 ]; then
			echo -n "F"
			RES_SIGSEGV=$((RES_SIGSEGV + 1))
		else
			echo -n "?"
		fi
	done

	# summary
	echo -ne "\n\t"
	echo "RES: GOOD:" $RES_GOOD ", BAD:" $RES_FAIL ", TIMEOUT:" $RES_TIMEOUT ", SIGSEGV:" $RES_SIGSEGV
	echo ""
}

# FA -> RG -> FA
# covers: FA -> LRG, FA -> RRG, RRG <-> LRG, RRG -> FA, LRG -> FA
runTest "./aconversion -t RRG | ./aconversion -t LRG | ./aconversion -t FA"
runTest "./aconversion -t LRG | ./aconversion -t RRG | ./aconversion -t FA"

# FA -> RE -> FA
# covers: FA -> RE (Brzozowski algebraic, elimination), RE -> FA (Brzozowski derivation, Thompson, Glushkov)
runTest "./aconversion -t RE -a algebraic | ./aconversion -t FA -a brzozowski"
runTest "./aconversion -t RE -a algebraic | ./aconversion -t FA -a thompson"
runTest "./aconversion -t RE -a algebraic | ./aconversion -t FA -a glushkov "
runTest "./aconversion -t RE -a elimination | ./aconversion -t FA -a brzozowski"
runTest "./aconversion -t RE -a elimination | ./aconversion -t FA -a thompson"
runTest "./aconversion -t RE -a elimination | ./aconversion -t FA -a glushkov"

# FA -> RE -> RRG -> LRG -> FA
# covers: FA -> RE (Brz. algebraic, elimination), RE -> RRG ( Brz. derivation, Glushkov), RRG -> LRG, LRG -> FA
runTest "./aconversion -t RE -a algebraic | ./aconversion -t RRG -a brzozowski | ./aconversion -t LRG | ./aconversion -t FA"
runTest "./aconversion -t RE -a algebraic | ./aconversion -t RRG -a glushkov | ./aconversion -t LRG | ./aconversion -t FA"
runTest "./aconversion -t RE -a elimination | ./aconversion -t RRG -a brzozowski | ./aconversion -t LRG | ./aconversion -t FA"
runTest "./aconversion -t RE -a elimination | ./aconversion -t RRG -a glushkov | ./aconversion -t LRG | ./aconversion -t FA"

# FA -> RRG -> RE -> FA
# covers: FA -> RRG, FA -> LRG, RRG -> RE, LRG -> RE, RE -> FA (Brz. derivation, Thompson, Glushkov)
runTest "./aconversion -t RRG | ./aconversion -t RE | ./aconversion -t FA -a brzozowski"
runTest "./aconversion -t LRG | ./aconversion -t RE | ./aconversion -t FA -a brzozowski"
runTest "./aconversion -t RRG | ./aconversion -t RE | ./aconversion -t FA -a thompson"
runTest "./aconversion -t LRG | ./aconversion -t RE | ./aconversion -t FA -a thompson"
runTest "./aconversion -t RRG | ./aconversion -t RE | ./aconversion -t FA -a glushkov"
runTest "./aconversion -t LRG | ./aconversion -t RE | ./aconversion -t FA -a glushkov"