Admin/mira.py
changeset 41790 a5478b1c8b8a
child 41802 6a515ace714b
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Admin/mira.py	Fri Jan 14 13:59:06 2011 +0100
     1.3 @@ -0,0 +1,254 @@
     1.4 +"""
     1.5 +    Test configuration descriptions for mira.
     1.6 +"""
     1.7 +
     1.8 +import os
     1.9 +from os import path
    1.10 +from glob import glob
    1.11 +import subprocess
    1.12 +import re
    1.13 +
    1.14 +import util
    1.15 +
    1.16 +from mira.environment import configuration
    1.17 +
    1.18 +from repositories import *
    1.19 +
    1.20 +
    1.21 +# build and evaluation tools
    1.22 +
    1.23 +def prepare_isabelle_repository(loc_isabelle, loc_contrib, loc_dependency_heaps, parallelism = True):
    1.24 +
    1.25 +    loc_contrib = path.expanduser(loc_contrib)
    1.26 +    if not path.exists(loc_contrib):
    1.27 +        raise IOError('Bad file: %s' % loc_contrib)
    1.28 +    subprocess.check_call(['ln', '-s', loc_contrib, '%s/contrib' % loc_isabelle])
    1.29 +
    1.30 +    contributed_components = path.join(loc_isabelle, 'Admin', 'contributed_components')
    1.31 +    if path.exists(contributed_components):
    1.32 +        components = []
    1.33 +        for component in util.readfile_lines(contributed_components):
    1.34 +            loc_component = path.join(loc_isabelle, component)
    1.35 +            if path.exists(loc_component):
    1.36 +                components.append(loc_component)
    1.37 +        writer = open(path.join(loc_isabelle, 'etc', 'components'), 'a')
    1.38 +        for component in components:
    1.39 +            writer.write(component + '\n')
    1.40 +        writer.close()
    1.41 +
    1.42 +    if loc_dependency_heaps:
    1.43 +        isabelle_path = loc_dependency_heaps + '/$ISABELLE_IDENTIFIER:$ISABELLE_OUTPUT'
    1.44 +    else:
    1.45 +        isabelle_path = '$ISABELLE_OUTPUT'
    1.46 +
    1.47 +    if parallelism:
    1.48 +        parallelism_options = '-M max'
    1.49 +    else:
    1.50 +        parallelism_options = '-M 1 -q 0'
    1.51 +
    1.52 +    extra_settings = '''
    1.53 +ISABELLE_HOME_USER="$ISABELLE_HOME/home_user"
    1.54 +ISABELLE_OUTPUT="$ISABELLE_HOME/heaps"
    1.55 +ISABELLE_BROWSER_INFO="$ISABELLE_HOME/browser_info"
    1.56 +ISABELLE_PATH="%s"
    1.57 +
    1.58 +ISABELLE_USEDIR_OPTIONS="$ISABELLE_USEDIR_OPTIONS %s -t true -v true -d pdf -g true -i true"
    1.59 +''' % (isabelle_path, parallelism_options)
    1.60 +
    1.61 +    writer = open(path.join(loc_isabelle, 'etc', 'settings'), 'a')
    1.62 +    writer.write(extra_settings)
    1.63 +    writer.close()
    1.64 +
    1.65 +
    1.66 +def extract_isabelle_run_timing(logdata):
    1.67 +
    1.68 +    def to_secs(h, m, s):
    1.69 +        return (int(h) * 60 + int(m)) * 60 + int(s)
    1.70 +    pat = r'Finished (\S+) \((\d+):(\d+):(\d+) elapsed time, (\d+):(\d+):(\d+) cpu time'
    1.71 +    pat2 = r'Timing (\S+) \((\d+) threads, (\d+\.\d+)s elapsed time, (\d+\.\d+)s cpu time, (\d+\.\d+)s GC time\)'
    1.72 +    t = dict((name, {'elapsed': to_secs(eh,em,es), 'cpu': to_secs(ch,cm,cs)})
    1.73 +             for name, eh, em, es, ch, cm, cs in re.findall(pat, logdata))
    1.74 +    for name, threads, elapsed, cpu, gc in re.findall(pat2, logdata):
    1.75 +
    1.76 +        if name not in t:
    1.77 +            t[name] = {}
    1.78 +
    1.79 +        t[name]['threads'] = int(threads)
    1.80 +        t[name]['elapsed_inner'] = elapsed
    1.81 +        t[name]['cpu_inner'] = cpu
    1.82 +        t[name]['gc'] = gc
    1.83 +
    1.84 +    return t
    1.85 +
    1.86 +
    1.87 +def extract_isabelle_run_summary(logdata):
    1.88 +
    1.89 +    re_error = re.compile(r'^\*\*\* (.*)$', re.MULTILINE)
    1.90 +    summary = '\n'.join(re_error.findall(logdata))
    1.91 +    if summary == '':
    1.92 +        summary = 'ok'
    1.93 +
    1.94 +    return summary
    1.95 +
    1.96 +
    1.97 +def isabelle_usedir(env, isa_path, isabelle_usedir_opts, base_image, dir_name):
    1.98 +
    1.99 +    return env.run_process('%s/bin/isabelle' % isa_path, 'usedir',
   1.100 +        isabelle_usedir_opts, base_image, dir_name)
   1.101 +
   1.102 +
   1.103 +def isabelle_dependency_only(env, case, paths, dep_paths, playground):
   1.104 +
   1.105 +    p = paths[0]
   1.106 +    result = path.join(p, 'heaps')
   1.107 +    os.makedirs(result)
   1.108 +    for dep_path in dep_paths:
   1.109 +        subprocess.check_call(['cp', '-R'] + glob(dep_path + '/*') + [result])
   1.110 +
   1.111 +    return (True, 'ok', {}, {}, result)
   1.112 +
   1.113 +
   1.114 +def build_isabelle_image(subdir, base, img, env, case, paths, dep_paths, playground):
   1.115 +
   1.116 +    p = paths[0]
   1.117 +    dep_path = dep_paths[0]
   1.118 +    prepare_isabelle_repository(p, env.settings.contrib, dep_path)
   1.119 +    os.chdir(path.join(p, 'src', subdir))
   1.120 +
   1.121 +    (return_code, log) = isabelle_usedir(env, p, '-b', base, img)
   1.122 +
   1.123 +    result = path.join(p, 'heaps')
   1.124 +    return (return_code == 0, extract_isabelle_run_summary(log),
   1.125 +      {'timing': extract_isabelle_run_timing(log)}, {'log': log}, result)
   1.126 +
   1.127 +
   1.128 +def isabelle_makeall(env, case, paths, dep_paths, playground):
   1.129 +
   1.130 +    p = paths[0]
   1.131 +    dep_path = dep_paths[0]
   1.132 +    prepare_isabelle_repository(p, env.settings.contrib, dep_path)
   1.133 +    os.chdir(p)
   1.134 +
   1.135 +    (return_code, log) = env.run_process('%s/bin/isabelle' % p, 'makeall', '-k', 'all')
   1.136 +
   1.137 +    return (return_code == 0, extract_isabelle_run_summary(log),
   1.138 +      {'timing': extract_isabelle_run_timing(log)}, {'log': log}, None)
   1.139 +
   1.140 +
   1.141 +# Isabelle configurations
   1.142 +
   1.143 +@configuration(repos = [Isabelle], deps = [])
   1.144 +def Pure(env, case, paths, dep_paths, playground):
   1.145 +    """Pure image"""
   1.146 +
   1.147 +    p = paths[0]
   1.148 +    prepare_isabelle_repository(p, env.settings.contrib, '')
   1.149 +    os.chdir(path.join(p, 'src', 'Pure'))
   1.150 +
   1.151 +    (return_code, log) = env.run_process('%s/bin/isabelle' % p, 'make', 'Pure')
   1.152 +
   1.153 +    result = path.join(p, 'heaps')
   1.154 +    return (return_code == 0, extract_isabelle_run_summary(log),
   1.155 +      {'timing': extract_isabelle_run_timing(log)}, {'log': log}, result)
   1.156 +
   1.157 +@configuration(repos = [Isabelle], deps = [(Pure, [0])])
   1.158 +def FOL(*args):
   1.159 +    """FOL image"""
   1.160 +    return build_isabelle_image('FOL', 'Pure', 'FOL', *args)
   1.161 +
   1.162 +@configuration(repos = [Isabelle], deps = [(Pure, [0])])
   1.163 +def HOL(*args):
   1.164 +    """HOL image"""
   1.165 +    return build_isabelle_image('HOL', 'Pure', 'HOL', *args)
   1.166 +
   1.167 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.168 +def HOL_HOLCF(*args):
   1.169 +    """HOL-HOLCF image"""
   1.170 +    return build_isabelle_image('HOL/HOLCF', 'HOL', 'HOLCF', *args)
   1.171 +
   1.172 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.173 +def HOL_Nominal(*args):
   1.174 +    """HOL-Nominal image"""
   1.175 +    return build_isabelle_image('HOL/Nominal', 'HOL', 'HOL-Nominal', *args)
   1.176 +
   1.177 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.178 +def HOL_Word(*args):
   1.179 +    """HOL-Word image"""
   1.180 +    return build_isabelle_image('HOL/Word', 'HOL', 'HOL-Word', *args)
   1.181 +
   1.182 +@configuration(repos = [Isabelle], deps = [
   1.183 +    (HOL, [0]),
   1.184 +    (HOL_HOLCF, [0]),
   1.185 +    (HOL_Nominal, [0]),
   1.186 +    (HOL_Word, [0])
   1.187 +  ])
   1.188 +def AFP_images(*args):
   1.189 +    """Isabelle images needed for the AFP"""
   1.190 +    return isabelle_dependency_only(*args)
   1.191 +
   1.192 +@configuration(repos = [Isabelle], deps = [
   1.193 +    (AFP_images, [0])
   1.194 +  ])
   1.195 +def Isabelle_makeall(*args):
   1.196 +    """Isabelle makeall"""
   1.197 +    return isabelle_makeall(*args)
   1.198 +
   1.199 +
   1.200 +# Mutabelle configurations
   1.201 +
   1.202 +def invoke_mutabelle(theory, env, case, paths, dep_paths, playground):
   1.203 +
   1.204 +    """Mutant testing for counterexample generators in Isabelle"""
   1.205 +
   1.206 +    (loc_isabelle,) = paths
   1.207 +    (dep_isabelle,) = dep_paths
   1.208 +    prepare_isabelle_repository(loc_isabelle, env.settings.contrib, dep_isabelle)
   1.209 +    os.chdir(loc_isabelle)
   1.210 +    
   1.211 +    (return_code, log) = env.run_process('bin/isabelle',
   1.212 +      'mutabelle', '-O', playground, theory)
   1.213 +    
   1.214 +    try:
   1.215 +        mutabelle_log = util.readfile(path.join(playground, 'log'))
   1.216 +    except IOError:
   1.217 +        mutabelle_log = ''
   1.218 +
   1.219 +    attachments = { 'log': log, 'mutabelle_log': mutabelle_log}
   1.220 +
   1.221 +    return (return_code == 0 and mutabelle_log != '', extract_isabelle_run_summary(log),
   1.222 +      {'timing': extract_isabelle_run_timing(log)}, {'log': log}, None)
   1.223 +
   1.224 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.225 +def Mutabelle_Relation(*args):
   1.226 +    """Mutabelle regression suite on Relation theory"""
   1.227 +    return invoke_mutabelle('Relation', *args)
   1.228 +
   1.229 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.230 +def Mutabelle_List(*args):
   1.231 +    """Mutabelle regression suite on List theory"""
   1.232 +    return invoke_mutabelle('List', *args)
   1.233 +
   1.234 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.235 +def Mutabelle_Set(*args):
   1.236 +    """Mutabelle regression suite on Set theory"""
   1.237 +    return invoke_mutabelle('Set', *args)
   1.238 +
   1.239 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.240 +def Mutabelle_Map(*args):
   1.241 +    """Mutabelle regression suite on Map theory"""
   1.242 +    return invoke_mutabelle('Map', *args)
   1.243 +
   1.244 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.245 +def Mutabelle_Divides(*args):
   1.246 +    """Mutabelle regression suite on Divides theory"""
   1.247 +    return invoke_mutabelle('Divides', *args)
   1.248 +
   1.249 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.250 +def Mutabelle_MacLaurin(*args):
   1.251 +    """Mutabelle regression suite on MacLaurin theory"""
   1.252 +    return invoke_mutabelle('MacLaurin', *args)
   1.253 +
   1.254 +@configuration(repos = [Isabelle], deps = [(HOL, [0])])
   1.255 +def Mutabelle_Fun(*args):
   1.256 +    """Mutabelle regression suite on Fun theory"""
   1.257 +    return invoke_mutabelle('Fun', *args)