src/HOL/Mutabelle/lib/Tools/mutabelle
author blanchet
Mon, 07 Nov 2011 14:16:01 +0100
changeset 45386 cfc8a0661310
parent 45227 f00a1aee5bc2
child 45397 20128348e9b9
permissions -rwxr-xr-x
align columns in output and keep error log around

#!/usr/bin/env bash
#
# Author: Lukas Bulwahn
#
# DESCRIPTION: mutant-testing for counterexample generators and automated tools


PRG="$(basename "$0")"

function usage() {
  [ -n "$MUTABELLE_OUTPUT_PATH" ] || MUTABELLE_OUTPUT_PATH="None"
  echo
  echo "Usage: isabelle $PRG [OPTIONS] THEORY"
  echo
  echo "  Options are:"
  echo "    -L LOGIC     parent logic to use (default $MUTABELLE_LOGIC)"
  echo "    -T THEORY    parent theory to use (default $MUTABELLE_IMPORT_THEORY)"
  echo "    -O DIR       output directory for test data (default $MUTABELLE_OUTPUT_PATH)"
  echo
  echo "  THEORY is the name of the theory of which all theorems should be"
  echo "  mutated and tested."
  echo
  exit 1
}


## process command line

# options

MUTABELLE_IMPORTS=""

while getopts "L:T:O:" OPT
do
  case "$OPT" in
    L)
      MUTABELLE_LOGIC="$OPTARG"
      ;;
    T)
      MUTABELLE_IMPORTS="$MUTABELLE_IMPORTS \"$OPTARG\""
      ;;
    O)      
      MUTABELLE_OUTPUT_PATH="$OPTARG"
      ;;
    \?)
      usage
      ;;
  esac
done

shift $(($OPTIND - 1))

if [ "$MUTABELLE_IMPORTS" = "" ]
then
  MUTABELLE_IMPORTS="$MUTABELLE_IMPORT_THEORY"
fi

[ "$#" -ne 1 ] && usage

MUTABELLE_TEST_THEORY="$1"

if [ -z "$MUTABELLE_OUTPUT_PATH" ]; then
  MUTABELLE_OUTPUT_PATH="${ISABELLE_TMP_PREFIX}-mutabelle$$"
  PURGE_OUTPUT="true"
fi

export MUTABELLE_OUTPUT_PATH


## main

echo "Starting Mutabelle..."


# setup

mkdir -p "$MUTABELLE_OUTPUT_PATH"

echo "theory Mutabelle_Test
imports \"~~/src/HOL/Library/Quickcheck_Narrowing\" $MUTABELLE_IMPORTS
uses     
  \"$MUTABELLE_HOME/mutabelle.ML\"
  \"$MUTABELLE_HOME/mutabelle_extra.ML\"
begin

declare [[quickcheck_timeout = 30]]

ML {*
val mtds = [
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"random\"])) \"random\",
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"exhaustive\"])) \"exhaustive\",
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"exhaustive\"]) #> Config.put Quickcheck.finite_types false) \"exhaustive_no_finite_types\",
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"narrowing\"]) #> Config.put Quickcheck.finite_types true) \"narrowing\",
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"narrowing\"]) #> Config.put Quickcheck.finite_types false) \"narrowing_no_finite_types\",
  MutabelleExtra.quickcheck_mtd (Context.proof_map (Quickcheck.set_active_testers [\"narrowing\"]) #> Config.put Quickcheck.finite_types false
    #> Context.proof_map (Quickcheck.map_test_params (apfst (K [@{typ nat}])))) \"narrowing_nat\"
(*  MutabelleExtra.nitpick_mtd *)
]
*}

ML {*
fun mutation_testing_of thy =
  (MutabelleExtra.random_seed := 1.0;
  MutabelleExtra.thms_of false thy
  |> (fn thms => MutabelleExtra.mutate_theorems_and_write_report
         @{theory} mtds thms (\"$MUTABELLE_OUTPUT_PATH/log\")))
*}

ML {*
  mutation_testing_of @{theory $MUTABELLE_TEST_THEORY}
*}

end" > "$MUTABELLE_OUTPUT_PATH/Mutabelle_Test.thy"


# execution

"$ISABELLE_PROCESS" -e 'use_thy "$MUTABELLE_OUTPUT_PATH/Mutabelle_Test"' -q "$MUTABELLE_LOGIC" > "$MUTABELLE_OUTPUT_PATH/err" 2>&1


[ $? -ne 0 ] && echo "isabelle processing of mutabelle failed"


# make statistics

function count() {
  cat "$MUTABELLE_OUTPUT_PATH/log" | grep "$1: $2" | wc -l
}

function mk_stat() {
  printf "%-40s : C: $(count $1 "GenuineCex") N: $(count $1 "NoCex") T: $(count $1 "Timeout") E: $(count $1 "Error")\n" "$1"
}

mk_stat "quickcheck_random"
mk_stat "quickcheck_exhaustive"
mk_stat "quickcheck_exhaustive_no_finite_types"
mk_stat "quickcheck_narrowing"
mk_stat "quickcheck_narrowing_no_finite_types"
mk_stat "quickcheck_narrowing_nat"
mk_stat "nitpick"

## cleanup

if [ -n "$PURGE_OUTPUT" ]; then
  rm -rf "$MUTABELLE_OUTPUT_PATH"
fi