def buildConfigSubstitution(test_pre_state, config_cells, skip_keys=[], debug_keys=[]): new_key_table = {} used_key_chains = [] for cell_var in config_cells: if cell_var not in skip_keys: (pre_keys, converter) = config_cells[cell_var] test_field = getKeyChain(test_pre_state, pre_keys) if test_field is None: _warning('Key not found: ' + str(pre_keys)) else: kast_term = converter(getKeyChain(test_pre_state, pre_keys)) if cell_var in debug_keys: _notif(cell_var) printerr(str(kast_term)) printerr(prettyPrintKast(kast_term, BEACON_CHAIN_symbols)) new_key_table[cell_var] = kast_term used_key_chains.append(pre_keys) else: _warning('Unset configuration variable: ' + cell_var) for yaml_chain in gatherKeyChains(test_pre_state): if not coversKeyChain(used_key_chains, yaml_chain): _warning('Unused yaml key: ' + str(yaml_chain)) return new_key_table
def _runK2(command, definition, kArgs = [], teeOutput = True, kRelease = None): if kRelease is not None: command = kRelease + '/bin/' + command elif 'K_RELEASE' in os.environ: command = os.environ['K_RELEASE'] + '/bin/' + command kCommand = [ command , definition ] + kArgs _notif('Running: ' + ' '.join(kCommand)) return pyk._teeProcessStdout(kCommand, tee = teeOutput)
def kompile_definition(definition_dir, backend, main_defn_file, main_module, kompileArgs = [], teeOutput = True, kRelease = None): command = 'kompile' if kRelease is not None: command = kRelease + '/bin/' + command elif 'K_RELEASE' in os.environ: command = os.environ['K_RELEASE'] + '/bin/' + command kCommand = [ command , '--backend' , backend , '--directory' , definition_dir , '-I' , definition_dir , '--main-module' , main_module , main_defn_file ] + kompileArgs _notif('Running: ' + ' '.join(kCommand)) return pyk._teeProcessStdout(kCommand, tee = teeOutput)
def kast_diff(kast1, kast2, kast1Caption, kast2Caption, allow_diff=True): if kast1 != kast2: header = 'WARNING' if allow_diff else 'ERROR' _notif('[%s] %s and %s differ!' % (header, kast1Caption, kast2Caption)) for line in difflib.unified_diff(kast1.split('\n'), kast2.split('\n'), fromfile=kast1Caption, tofile=kast2Caption, lineterm='\n'): sys.stderr.write(line + '\n') sys.stderr.flush() if not allow_diff: sys.exit(3)
def mergeRulesKoreExec(definition_dir, ruleList, kArgs = [], teeOutput = True, kRelease = None, symbolTable = None, definition = None): if symbolTable is not None and definition is not None: _notif('Merging rules:') for rule in ruleList: print() print('rule: ' + rule) print(prettyPrintRule(getRuleById(definition, rule), symbolTable)) sys.stdout.flush() with tempfile.NamedTemporaryFile(mode = 'w') as tempf: tempf.write('\n'.join(ruleList)) tempf.flush() sys.stdout.write('\n'.join(ruleList)) sys.stdout.flush() return _runK2('kore-exec', definition_dir, kArgs = ['--merge-rules', tempf.name] + kArgs, teeOutput = teeOutput, kRelease = kRelease)
def mergeRules(definition_dir, main_defn_file, main_module, subsequence, symbolTable = None, definition = None): (rc, stdout, stderr) = mergeRulesKoreExec(definition_dir + '/' + main_defn_file + '-kompiled/definition.kore', subsequence, kArgs = ['--module', main_module], symbolTable = symbolTable, definition = definition) if rc == 0: with tempfile.NamedTemporaryFile(mode = 'w') as tempf: tempf.write(stdout) tempf.flush() (_, stdout, stderr) = pyk.kast(definition_dir, tempf.name, kastArgs = ['--input', 'kore', '--output', 'json']) merged_rule = json.loads(stdout)['term'] rule_pattern = KRewrite(KApply('#And', [KVariable('#CONSTRAINT'), KVariable('#INITTERM')]), KVariable('#FINALTERM')) rule_subst = pyk.match(rule_pattern, merged_rule) rule_body = pyk.KRewrite(rule_subst['#INITTERM'], rule_subst['#FINALTERM']) gen_rule = pyk.KRule(rule_body, requires = rule_subst['#CONSTRAINT']) if symbolTable is not None: _notif('Merged rule:') print(prettyPrintRule(gen_rule, symbolTable)) sys.stdout.flush() return gen_rule else: print(stderr) _warning('Cannot merge rules!') return None
def mergeRules(definition_dir, main_defn_file, main_module, subsequence, symbolTable = None, definition = None): (returnCode, stdout, stderr) = mergeRulesKoreExec(definition_dir + '/' + main_defn_file + '-kompiled/definition.kore', subsequence, kArgs = ['--module', main_module], symbolTable = symbolTable, definition = definition) if returnCode == 0: with tempfile.NamedTemporaryFile(mode = 'w') as tempf: tempf.write(stdout) tempf.flush() (returnCode, stdout, stderr) = pyk.kast(definition_dir, tempf.name, kastArgs = ['--input', 'kore', '--output', 'json']) if returnCode != 0: print(stderr) _warning('Cannot merge rules!') return None merged_rule = json.loads(stdout)['term'] (lhs_term, lhs_constraint) = extractTermAndConstraint(merged_rule['lhs']) (rhs_term, rhs_constraint) = extractTermAndConstraint(merged_rule['rhs']) gen_rule = pyk.KRule(KRewrite(lhs_term, rhs_term), requires = lhs_constraint, ensures = rhs_constraint) if symbolTable is not None: _notif('Merged rule:') print(prettyPrintRule(gen_rule, symbolTable)) sys.stdout.flush() return gen_rule else: print(stderr) _warning('Cannot merge rules!') return None
files = os.listdir(path) return [ path + '/' + f for f in files if f.endswith('_coverage.txt') ] def krunCoverage(inputJson, *krunArgs): for f in findCoverageFiles(WASM_definition_llvm_coverage_dir + '/' + WASM_definition_main_file + '-kompiled'): os.remove(f) ret = pyk.krunJSON(WASM_definition_llvm_coverage_dir, inputJson, krunArgs = list(krunArgs)) [ coverageFile ] = findCoverageFiles(WASM_definition_llvm_coverage_dir + '/' + WASM_definition_main_file + '-kompiled') return coverageFile def kprove(inputJson, *krunArgs): return pyk.kproveJSON(WASM_definition_llvm_no_coverage, inputJson, kproveArgs = list(kproveArgs)) ################################################################################ # Main Functionality # ################################################################################ def get_init_config(): init_term = { 'format': 'KAST', 'version': 1, 'term': KConstant('.List{"___WASM_Stmts_Stmt_Stmts"}_Stmts') } (_, simple_config, _) = krun(init_term) return pyk.splitConfigFrom(simple_config) if __name__ == '__main__': (generatedTop, initSubst) = get_init_config() initial_configuration = pyk.substitute(generatedTop, initSubst) kast_json = { 'format': 'KAST', 'version': 1, 'term': initial_configuration } fastPrinted = pyk.prettyPrintKast(initial_configuration['args'][0], WASM_symbols_llvm_no_coverage) _notif('fastPrinted output') print(fastPrinted)
def main(): arguments = argparse.ArgumentParser(prog=sys.argv[0]) arguments.add_argument('command', choices=['parse']) arguments.add_argument('-o', '--output', type=argparse.FileType('w'), default='-') arguments.add_argument('--test', type=argparse.FileType('r'), default='-') arguments.add_argument('--allow-diff', dest='allow_diff', action='store_true') arguments.add_argument('-d', '--debug', dest='debug', action='store_true') arguments.add_argument('-b', '--backend') args = arguments.parse_args() test_dir = Path(args.test.name).parent test_title = str(test_dir) _notif(test_title) (generated_top_config, init_subst) = get_init_config(args.backend) init_config_subst = copy.deepcopy(init_subst) all_keys = list(init_subst.keys()) init_config_subst.update(buildPreConfigSubst(test_dir)) # build state init_config_subst['K_CELL'] = buildKCell(test_dir) # build <k> init_config = substitute(generated_top_config, init_config_subst) kast_json = {'format': 'KAST', 'version': 1.0, 'term': init_config} with tempfile.NamedTemporaryFile(mode='w', delete=not args.debug) as pre_json_file: json.dump(kast_json, pre_json_file) pre_json_file.flush() fastPrinted = prettyPrintKast(init_config['args'][0], beacon_chain_symbols( args.backend)).strip() _notif('kast content') print(fastPrinted, file=sys.stderr, flush=True) kastPrinted = fastPrinted # ISSUE: kast does not work with KSequence of 2 elements in <k>. # (returnCode, kastPrinted, _) = kast(pre_json_file.name, '--input', 'json', '--output', 'pretty', '--debug') # if returnCode != 0: # _fatal('kast returned non-zero exit code: ' + test_title, code = returnCode) kastPrinted = kastPrinted.strip() kast_diff(kastPrinted, fastPrinted, 'kastPrinted', 'fastPrinted') krun_args = [ pre_json_file.name, args.backend, '--term', '--parser', 'cat' ] if args.debug: krun_args.append('--debug') (returnCode, krunPrinted, _) = krun(*krun_args) krunPrinted = krunPrinted.strip() meta_yaml = loadYaml(test_dir, "meta.yaml") if meta_yaml is not None and 'bls_setting' in meta_yaml and meta_yaml[ 'bls_setting'] == 1: _warning('`bls_setting` enabled: skipping post-state verification') return # Printing the post state post_yaml = loadYaml(test_dir, getPostFile(test_dir)) post_k_cell = buildPostKCell(test_dir) if post_yaml is not None or post_k_cell is not None: if returnCode != 0: _fatal('krun returned non-zero exit code for positive test: ' + test_title, code=returnCode) post_config_subst = copy.deepcopy(init_config_subst) if post_yaml is not None: post_config_subst.update( buildConfigSubstitution(post_yaml, init_config_cells, skip_keys=skip_keys, debug_keys=debug_keys)) post_config_subst[ 'K_CELL'] = post_k_cell if post_k_cell is not None else KConstant( 'init') post_config = substitute(generated_top_config, post_config_subst) post_kast_json = { 'format': 'KAST', 'version': 1.0, 'term': post_config } with tempfile.NamedTemporaryFile( mode='w', delete=not args.debug) as post_json_file: json.dump(post_kast_json, post_json_file) post_json_file.flush() # (returnCode, postKastPrinted, _) = kast(post_json_file.name, '--input', 'json', '--output', 'pretty', '--debug') # Using krun to get same string encoding as for main krun (returnCode, postKastPrinted, _) = krun(post_json_file.name, args.backend, '--term', '--parser', 'cat') postKastPrinted = postKastPrinted.strip() if returnCode != 0: _fatal('kast returned non-zero exit code: ' + test_title, code=returnCode) kast_diff(krunPrinted, postKastPrinted, 'krun_out', 'expected_post_state', args.allow_diff) else: # negative tests if returnCode != 0: print('\nNegative test passed. Exit code: %d' % returnCode, flush=True) else: empty_k_match = re.search(re.compile('<k>\\s*\\.\\s*</k>'), krunPrinted) if empty_k_match is None: print('\nNegative test passed. Non-empty <k>', flush=True) else: _fatal( '\nkrun returned zero exit code and empty <k> for negative test' )