Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add toml support for pyk options #4254

Merged
merged 33 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a1260b0
added toml reading options
ovatman Mar 20, 2024
e67699c
format fixes
ovatman Mar 20, 2024
08d9df9
reorganized and added unit tests
ovatman Mar 20, 2024
82a523f
fixed import sorting
ovatman Mar 20, 2024
b65a244
fixed missing warning_args parent
ovatman Mar 21, 2024
6c46dad
code formatting fixes
ovatman Mar 21, 2024
c29df3d
removed config args form legacy commands
ovatman Mar 21, 2024
3eb9c48
handles missing config_file attribute
ovatman Mar 21, 2024
47195c1
fixed underscore error
ovatman Mar 25, 2024
f5c2ec9
toml dict key fix
ovatman Mar 25, 2024
83c4d44
toml parser typing fix
ovatman Mar 25, 2024
fd7633c
removed redundant agrument in test
ovatman Mar 25, 2024
4a19726
added toml reading options
ovatman Mar 20, 2024
d4dc504
format fixes
ovatman Mar 20, 2024
00b81f9
reorganized and added unit tests
ovatman Mar 20, 2024
8732138
fixed optimization level parameter
ovatman Apr 16, 2024
112f27f
final fixes from merge conflict errors
ovatman Apr 16, 2024
a37f075
latest argument additions reflected
ovatman Apr 18, 2024
c00c7bc
added toml reading options
ovatman Mar 20, 2024
1377824
format fixes
ovatman Mar 20, 2024
bca6963
reorganized and added unit tests
ovatman Mar 20, 2024
f427275
added toml reading options
ovatman Mar 20, 2024
e64655e
format fixes
ovatman Mar 20, 2024
4a55c57
latest argument additions reflected
ovatman Apr 18, 2024
68705e1
more fixes for errors missed during rebasing
ovatman Apr 18, 2024
ed0295d
Allow a custom `--kore-rpc-command` in `pyk prove` (#4241)
geo2a Apr 18, 2024
cdd3551
Pyk: Attribute token locations (#4252)
gtrepta Apr 18, 2024
82a2711
Update dependency: llvm-backend/src/main/native/llvm-backend (#4268)
rv-jenkins Apr 19, 2024
8d34a45
Merge branch 'develop' into tolga/toml-options-rebased
ovatman Apr 22, 2024
9fff9ee
format check fix
ovatman Apr 22, 2024
cdac867
Merge branch 'develop' into tolga/toml-options-rebased
ovatman Apr 22, 2024
1964aa9
Merge branch 'develop' into tolga/toml-options-rebased
ovatman Apr 24, 2024
287a4ff
Merge branch 'develop' into tolga/toml-options-rebased
rv-jenkins Apr 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 5 additions & 156 deletions pyk/src/pyk/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
import json
import logging
import sys
from argparse import ArgumentParser, FileType
from collections.abc import Iterable
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING

from graphviz import Digraph

from .cli.args import KCLIArgs
from .cli.pyk import generate_options
from .cli.utils import LOG_FORMAT, dir_path, loglevel
from .cli.pyk import PrintInput, create_argument_parser, generate_options, parse_toml_args
from .cli.utils import LOG_FORMAT, loglevel
from .coverage import get_rule_by_id, strip_coverage_logger
from .cterm import CTerm
from .kast.inner import KInner
Expand Down Expand Up @@ -61,11 +58,6 @@
_LOGGER: Final = logging.getLogger(__name__)


class PrintInput(Enum):
KORE_JSON = 'kore-json'
KAST_JSON = 'kast-json'


def main() -> None:
# KAST terms can end up nested quite deeply, because of the various assoc operators (eg. _Map_, _Set_, ...).
# Most pyk operations are defined recursively, meaning you get a callstack the same depth as the term.
Expand All @@ -74,10 +66,12 @@ def main() -> None:

cli_parser = create_argument_parser()
args = cli_parser.parse_args()
toml_args = parse_toml_args(args)

stripped_args = {
stripped_args = toml_args | {
key: val for (key, val) in vars(args).items() if val is not None and not (isinstance(val, Iterable) and not val)
}

options = generate_options(stripped_args)

logging.basicConfig(level=loglevel(args), format=LOG_FORMAT)
Expand Down Expand Up @@ -389,150 +383,5 @@ def exec_json_to_kore(options: JsonToKoreOptions) -> None:
sys.stdout.write('\n')


def create_argument_parser() -> ArgumentParser:
k_cli_args = KCLIArgs()

pyk_args = ArgumentParser()
pyk_args_command = pyk_args.add_subparsers(dest='command', required=True)

print_args = pyk_args_command.add_parser(
'print',
help='Pretty print a term.',
parents=[k_cli_args.logging_args, k_cli_args.display_args],
)
print_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')
print_args.add_argument('term', type=FileType('r'), help='Input term (in format specified with --input).')
print_args.add_argument('--input', type=PrintInput, choices=list(PrintInput))
print_args.add_argument('--omit-labels', nargs='?', help='List of labels to omit from output.')
print_args.add_argument('--keep-cells', nargs='?', help='List of cells with primitive values to keep in output.')
print_args.add_argument('--output-file', type=FileType('w'))

rpc_print_args = pyk_args_command.add_parser(
'rpc-print',
help='Pretty-print an RPC request/response',
parents=[k_cli_args.logging_args],
)
rpc_print_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')
rpc_print_args.add_argument(
'input_file',
type=FileType('r'),
help='An input file containing the JSON RPC request or response with KoreJSON payload.',
)
rpc_print_args.add_argument('--output-file', type=FileType('w'))

rpc_kast_args = pyk_args_command.add_parser(
'rpc-kast',
help='Convert an "execute" JSON RPC response to a new "execute" or "simplify" request, copying parameters from a reference request.',
parents=[k_cli_args.logging_args],
)
rpc_kast_args.add_argument(
'reference_request_file',
type=FileType('r'),
help='An input file containing a JSON RPC request to server as a reference for the new request.',
)
rpc_kast_args.add_argument(
'response_file',
type=FileType('r'),
help='An input file containing a JSON RPC response with KoreJSON payload.',
)
rpc_kast_args.add_argument('--output-file', type=FileType('w'))

prove_legacy_args = pyk_args_command.add_parser(
'prove-legacy',
help='Prove an input specification (using kprovex).',
parents=[k_cli_args.logging_args],
)
prove_legacy_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')
prove_legacy_args.add_argument('main_file', type=str, help='Main file used for kompilation.')
prove_legacy_args.add_argument('spec_file', type=str, help='File with the specification module.')
prove_legacy_args.add_argument('spec_module', type=str, help='Module with claims to be proven.')
prove_legacy_args.add_argument('--output-file', type=FileType('w'))
prove_legacy_args.add_argument('kArgs', nargs='*', help='Arguments to pass through to K invocation.')

kompile_args = pyk_args_command.add_parser(
'kompile',
help='Kompile the K specification.',
parents=[k_cli_args.logging_args, k_cli_args.warning_args, k_cli_args.definition_args, k_cli_args.kompile_args],
)
kompile_args.add_argument('main_file', type=str, help='File with the specification module.')

run_args = pyk_args_command.add_parser(
'run',
help='Run a given program using the K definition.',
parents=[k_cli_args.logging_args],
)
run_args.add_argument('pgm_file', type=str, help='File program to run in it.')
run_args.add_argument('--definition', type=dir_path, dest='definition_dir', help='Path to definition to use.')

prove_args = pyk_args_command.add_parser(
'prove',
help='Prove an input specification (using RPC based prover).',
parents=[k_cli_args.logging_args, k_cli_args.spec_args],
)
prove_args.add_argument(
'--failure-info',
default=None,
action='store_true',
help='Print out more information about proof failures.',
)
prove_args.add_argument(
'--show-kcfg',
default=None,
action='store_true',
help='Display the resulting proof KCFG.',
)
prove_args.add_argument(
'--max-depth',
type=int,
help='Maximum number of steps to take in symbolic execution per basic block.',
)
prove_args.add_argument(
'--max-iterations',
type=int,
help='Maximum number of KCFG explorations to take in attempting to discharge proof.',
)

show_args = pyk_args_command.add_parser(
'show',
help='Display the status of a given proof.',
parents=[k_cli_args.logging_args, k_cli_args.spec_args],
)
show_args.add_argument(
'--failure-info',
default=None,
action='store_true',
help='Print out more information about proof failures.',
)
prove_args.add_argument(
'--kore-rpc-command',
dest='kore_rpc_command',
type=str,
default=None,
help='Custom command to start RPC server.',
)

graph_imports_args = pyk_args_command.add_parser(
'graph-imports',
help='Graph the imports of a given definition.',
parents=[k_cli_args.logging_args],
)
graph_imports_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')

coverage_args = pyk_args_command.add_parser(
'coverage',
help='Convert coverage file to human readable log.',
parents=[k_cli_args.logging_args],
)
coverage_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')
coverage_args.add_argument('coverage_file', type=FileType('r'), help='Coverage file to build log for.')
coverage_args.add_argument('-o', '--output', type=FileType('w'))

pyk_args_command.add_parser('kore-to-json', help='Convert textual KORE to JSON', parents=[k_cli_args.logging_args])

pyk_args_command.add_parser('json-to-kore', help='Convert JSON to textual KORE', parents=[k_cli_args.logging_args])

return pyk_args


if __name__ == '__main__':
main()
71 changes: 71 additions & 0 deletions pyk/src/pyk/cli/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ def default() -> dict[str, Any]:
'debug': False,
}

@staticmethod
def from_option_string() -> dict[str, Any]:
return {
'v': 'verbose',
}


class WarningOptions(Options):
warnings: Warnings | None
Expand All @@ -39,6 +45,13 @@ def default() -> dict[str, Any]:
'warnings_to_errors': False,
}

@staticmethod
def from_option_string() -> dict[str, Any]:
return {
'w': 'warnings',
'w2e': 'warning_to_error',
}


class OutputFileOptions(Options):
output_file: IO[Any]
Expand All @@ -53,6 +66,13 @@ def default() -> dict[str, Any]:
class DefinitionOptions(Options):
definition_dir: Path

@staticmethod
def default() -> dict[str, Any]:
return {
'output-definition': 'definition_dir',
'definition': 'definition_dir',
}


class DisplayOptions(Options):
minimize: bool
Expand Down Expand Up @@ -81,6 +101,12 @@ def default() -> dict[str, Any]:
'includes': [],
}

@staticmethod
def from_option_string() -> dict[str, str]:
return {
'includes': 'includes',
}


class SaveDirOptions(Options):
save_directory: Path | None
Expand Down Expand Up @@ -108,6 +134,13 @@ def default() -> dict[str, Any]:
'exclude_claim_labels': None,
}

@staticmethod
def from_option_string() -> dict[str, str]:
return SaveDirOptions.from_option_string() | {
'claim': 'claim_labels',
'exclude-claim': 'exclude_claim_labels',
}


class KompileOptions(Options):
emit_json: bool
Expand Down Expand Up @@ -154,6 +187,18 @@ def default() -> dict[str, Any]:
'no_exc_wrap': False,
}

@staticmethod
def from_option_string() -> dict[str, str]:
return {
'with-llvm-library': 'llvm_library',
'read-only-kompiled-directory': 'read_only',
'ccopt': 'ccopts',
'O0': 'o0',
'O1': 'o1',
'O2': 'o2',
'O3': 'o3',
}


class ParallelOptions(Options):
workers: int
Expand All @@ -164,6 +209,12 @@ def default() -> dict[str, Any]:
'workers': 1,
}

@staticmethod
def from_option_string() -> dict[str, str]:
return {
'j': 'workers',
}


class BugReportOptions(Options):
bug_report: BugReport | None
Expand All @@ -187,6 +238,26 @@ def default() -> dict[str, Any]:
}


class ConfigArgs:
@cached_property
def config_args(self) -> ArgumentParser:
args = ArgumentParser(add_help=False)
args.add_argument(
'--config-file',
dest='config_file',
type=file_path,
default=Path('./pyk.toml'),
help='Path to Pyk config file.',
)
args.add_argument(
'--config-profile',
dest='config_profile',
default='default',
help='Config profile to be used.',
)
return args


class KCLIArgs:
@cached_property
def logging_args(self) -> ArgumentParser:
Expand Down
4 changes: 4 additions & 0 deletions pyk/src/pyk/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ def __init__(self, args: dict[str, Any]) -> None:

for attr, val in _args.items():
self.__setattr__(attr, val)

@staticmethod
def from_option_string() -> dict[str, str]:
return {}
Loading
Loading