#!/bin/bash
#set -x
#########################################################################
# This file is part of the Kind 2 model checker.                        #
#                                                                       #
# Copyright (c) 2014 by the Board of Trustees of the University of Iowa #
#                                                                       #
# Licensed under the Apache License, Version 2.0 (the "License"); you   #
# may not use this file except in compliance with the License.  You     #
# may obtain a copy of the License at                                   #
#                                                                       #
# http://www.apache.org/licenses/LICENSE-2.0                            #
#                                                                       #
# Unless required by applicable law or agreed to in writing, software   #
# distributed under the License is distributed on an "AS IS" BASIS,     #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or       #
# implied. See the License for the specific language governing          #
# permissions and limitations under the License.                        #
#########################################################################


# Small script to run cvc5 with proof production, extract the goal from the
# proof tree and check the equivalence with the original smt2 file using Z3.
#
# run it like this: cvc5_lfsc_check file.smt2
# change the paths cvc5, Z3, LFSCEX to the correct ones

# default values

if [ -z $TMPDIR ]; then
    TMPDIR="/tmp"
fi

TIMEOUT=""
TOCODE=@TOCODE@

# binaries
CVC5="cvc5"
Z3="z3"
LFSCEX="lfsc-extractor"

# default return code (to be overwritten)
RET=127


# parsing command line arguments
while [[ $# > 1 ]]
do
    key="$1"

    case $key in
        -t|--timeout)
            TIMEOUT="timeout $2"
            shift
            ;;
        -cvc5|--cvc5)
            CVC5="$2"
            shift
            ;;
        -s|--solver)
            Z3="$2"
            shift
            ;;
        -l|--lfscex)
            LFSCEX="$2"
            shift
            ;;
        *)
            echo "Unknown option $1"
            echo "Usage $(basename $0) [-t <timeout>] [-cvc5 <cvc5_binary>] [-solver <solver_binary>] [-l <lfsc-extractor>] file.smt2"
            exit 1
            ;;
    esac
    shift
done


# temporary files
lfsc_tmp="$TMPDIR/$(basename $1).lfsc"
smt2_eq="$TMPDIR/$(basename $1).lfsc_eq.smt2"
eq_res="$TMPDIR/$(basename $1).eq_check"


# colors
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
NC='\033[0m' # No Color


function print_end () {
    text=$2
    color=$1
    tput cuu1
    tput cuf $(tput cols)
    length=${#text}
    tput cub $(($length+1))
    echo -e "${!color}[$text]${NC}"
}

echo "Running cvc5 with proofs on $1"
$TIMEOUT $CVC5 --proof --check-proofs --dump-proof $1 > $lfsc_tmp
RET=$?

SAT=$(grep -q "^sat" $lfsc_tmp; echo $?)

if [ $SAT = 0 ]; then
    print_end BLUE SAT
    exit $RET
fi

case $RET in
    0)
        print_end GREEN OK
        ;;
    $TOCODE)
        print_end YELLOW CVC5_TIMEOUT
        exit $RET
        ;;
    *)
        print_end RED LFSC_FAILED
        exit $RET
        ;;
esac


echo "Proof written in $lfsc_tmp"
echo

echo "Extracting forumla from lfsc proof"
$TIMEOUT $LFSCEX $1 $lfsc_tmp > $smt2_eq
RET=$?


case $RET in
    0)
        print_end GREEN OK
        ;;
    $TOCODE)
        print_end YELLOW LFSCEX_TIMEOUT
        exit $RET
        ;;
    *)
        print_end RED LFSCEX_FAILED
        exit $RET
        ;;
esac


echo "Equivalence goal written in $smt2_eq"
echo


echo "Checking equivalence with $(basename $Z3)"
$TIMEOUT $Z3 $smt2_eq &> $eq_res
RET=$?

if [ $RET -ne $TOCODE ]; then
    cat $eq_res
    grep -q "^unsat" $eq_res
    RET=$?
    
fi

case $RET in
    0)
        print_end GREEN OK
        ;;
    $TOCODE)
        print_end YELLOW EQ_TIMEOUT
        exit $RET
        ;;
    *)
        print_end RED EQ_FAILED
        exit $RET
        ;;
esac


echo
echo "Verified"


exit $RET

