I'm working in testing my smt model using different solvers. In this moment I have the file .smt2 which contains the instruction of a model converted in smtlib.
I have created a file .sh which implements the linear search in order to test my model using different solvers.
This is the code of my bash file:
#!/bin/bash
# Usage:
# ./smt-opt <SMT-LIB file> <obj.var name> <initial bound> <solver> <min/max>
# No (get-model) query should in the SMT-LIB input file.
TIMEOUT=300 # Timeout in seconds. TODO: Set timeout as a parameter.
in_file=$1
obj_var=$2
obj_val=$3
if
[ "$4" = 'z3' ];
then
solver_cmd="z3 -in "
elif
[ "$4" = 'cvc4' ];
then
solver_cmd="cvc4 --lang smt --produce-models --incremental "
elif
[ "$4" = 'cvc5' ];
then
solver_cmd="cvc5 --produce-models --incremental "
else
echo "Unknown solver!"
exit 1
fi
if [ "$5" = 'max' ]; then
# Maximization problem.
rel='>='
next=1
else
# Minimization problem.
rel='<='
next=-1
fi
# Creating input/output pipes.
in_pipe=pipe.in
out_pipe=pipe.out
rm $in_pipe $out_pipe pkill sleep 2>/dev/null
mkfifo $in_pipe
mkfifo $out_pipe
# Block input pipe for $TIMEOUT seconds.
sleep $TIMEOUT > $in_pipe &
# Send piped input data to solver, and the output of solver to output pipe.
$solver_cmd < $in_pipe > $out_pipe &
# Feed input pipe with the queries SMT-LIB specified in the input file.
cat $in_file > $in_pipe
# SOL = 0 iff solver hasn't find any solution yet.
SOL=0
while read line < $out_pipe
do
if [ ! "$line" = 'sat' ]; then
break;
fi
SOL=1
echo -e "$obj_var = $obj_val\n----------"
# Updating obj. value (linear search). TODO: Implement binary search.
obj_val=`awk -v ov=$obj_val -v n=$next 'BEGIN {ov = int(ov) + n; print ov}'`
if
[ $obj_val -lt 0 ]
then
# Adjusting for unary minus.
echo "(assert ($rel $obj_var (-"`echo $obj_val | tr '-' ' '`")))" > $in_pipe
else
echo "(assert ($rel $obj_var $obj_val))" > $in_pipe
fi
echo "(check-sat)" > $in_pipe
# echo "%%% Solving with $obj_var $rel $obj_val"
done
if
[[ $SOL -eq 0 ]]
then
if [ "$line" = 'unsat' ]; then
echo '=====UNSATISFIABLE====='
else
echo '=====UNKNOWN====='
fi
elif [ "$line" = 'unsat' ]; then
echo '=========='
fi
rm $in_pipe $out_pipe pkill sleep 2>/dev/null
In particular my problem is in this line:
cat $in_file > $in_pipe
The problem of this instruction is that it takes a lot of times (the dimension of my smtlib file is 80 megabytes). How can I substitute this instruction in order to have a more efficient instruction ?
I am expecting a more efficient instruction which works for this project.
cat
itself is very fast; if it's being slow here, that's because you're trying to do I/O that's slow, not becausecat
incurs unreasonable overhead. There are certainly alternatives, but none of them will be faster; either reading the input file is slow, or writing to the pipe is slow (and if the latter is the case, probably that's because the thing on the read side of the pipe is being slow).$solver_cmd
is inherently bug-prone; see BashFAQ #50.read
operation is much, much slower thancat
is.