#! /usr/bin/env python3 import os import argparse import subprocess import sys def shell(command, expect=0, cwd=None, env={}): subprocess_stdout = subprocess.DEVNULL print("Env:", env) print("Command: ", end="") for i, word in enumerate(command): if i == 4: print("'{}' ".format(word), end="") else: print("{} ".format(word), end="") print("\nDirectory: {}".format(cwd)) os_env = os.environ os_env.update(env) ret = subprocess.run(command, cwd=cwd, env=os_env) if ret.returncode != expect: raise Exception("Error {}. Expected {}.".format(ret, expect)) class extractAction(argparse.Action): def __call__(self, parser, args, values, option_string=None) -> None: # Extract spqr include_str = "-**::proto::** +:**::proto::**" if args.include: include_str = "-** +:**::proto::** " + args.include if args.encoding: include_str = "-** +:**::proto::** +**::encoding::**" interface_include = "+**::proto::**" cargo_hax_into = [ "cargo", "hax", "into", "-i", include_str, "fstar", "--interfaces", interface_include, ] hax_env = {} shell( cargo_hax_into, cwd=".", env=hax_env, ) return None class proveAction(argparse.Action): def __call__(self, parser, args, values, option_string=None) -> None: admit_env = {} if args.admit: admit_env = {"OTHERFLAGS": "--admit_smt_queries true"} shell(["make", "-C", "proofs/fstar/extraction/"], env=admit_env) return None def parse_arguments(): parser = argparse.ArgumentParser( description="SPQR prove script. " + "Make sure to separate sub-command arguments with --." ) subparsers = parser.add_subparsers() extract_parser = subparsers.add_parser( "extract", help="Extract the F* code for the proofs." ) extract_parser.add_argument( "--include", required=False, help="Include flag to pass to hax.", ) extract_parser.add_argument( "--encoding", help="Extract only encoding module.", action="store_true", ) extract_parser.add_argument("extract", nargs="*", action=extractAction) prover_parser = subparsers.add_parser( "prove", help=""" Run F*. This typechecks the extracted code. To lax-typecheck use --admit. """, ) prover_parser.add_argument( "--admit", help="Admit all smt queries to lax typecheck.", action="store_true", ) prover_parser.add_argument( "prove", nargs="*", action=proveAction, ) if len(sys.argv) == 1: parser.print_help(sys.stderr) sys.exit(1) return parser.parse_args() def main(): # Don't print unnecessary Python stack traces. sys.tracebacklimit = 0 parse_arguments() if __name__ == "__main__": main()