Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

Improve default argument handling #916

Merged
merged 97 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
e8a4dca
Add ProveOptions and PrintOptions
nwatson22 Feb 24, 2024
6c8fee8
Merge e8a4dcabe83e42374e289ec804c7eee439ece97a into e1b9407afc8cce2be…
nwatson22 Feb 24, 2024
573ba5d
Set Version: 0.1.652
Feb 24, 2024
281a027
Add other commands
nwatson22 Feb 26, 2024
8c990aa
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Feb 26, 2024
c82090f
Remove default values from add_argument
nwatson22 Feb 26, 2024
e1c762b
Handle parsing within Options classes
nwatson22 Feb 27, 2024
e34d109
Add comments
nwatson22 Feb 27, 2024
4f75918
Use classes in exec_ functions
nwatson22 Feb 27, 2024
0532f8f
Merge branch 'master' into noah/default-options
nwatson22 Feb 27, 2024
40de753
Merge 0532f8fa0b563291a0f050c98da917a736b9f87e into a8a749d97f514f196…
nwatson22 Feb 27, 2024
809470b
Set Version: 0.1.655
Feb 27, 2024
d528eaa
Update src/pyk/cli/args.py
nwatson22 Feb 27, 2024
ea274bc
Merge d528eaa976d1818d7f399ae5b307681833f1da63 into 50774da36c4e5d2e4…
nwatson22 Feb 27, 2024
f2e5cc6
Set Version: 0.1.656
Feb 27, 2024
031e141
Update src/pyk/cli/args.py
nwatson22 Feb 27, 2024
6e35eaa
Fix pyupgrade
nwatson22 Feb 27, 2024
19b4834
Fix pyupgrade
nwatson22 Feb 27, 2024
2eb34c6
Merge master into branch
nwatson22 Feb 27, 2024
20d2ec6
Merge 2eb34c60d9e59714603d1dacdd58b725adf480c5 into 9dcfe3987ab021561…
nwatson22 Feb 27, 2024
7bd95b1
Set Version: 0.1.658
Feb 27, 2024
91d80eb
Merge remote-tracking branch 'origin/master' into noah/default-options
nwatson22 Feb 27, 2024
2e01912
Fix rpc-kast gettting definition options, fix changed options ordering
nwatson22 Feb 27, 2024
580a3ae
Merge master into branch
nwatson22 Feb 27, 2024
30f95e5
Merge 580a3ae96973f33666e1f88a2aceb67a9009ee9e into a71358f956e5fc4d7…
nwatson22 Feb 27, 2024
18f5804
Set Version: 0.1.660
Feb 27, 2024
b31ac24
Extend timout for pyk integration tests
nwatson22 Feb 27, 2024
0fe40f5
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Feb 27, 2024
dc906e5
Move definition_args to KDefinitionOptions
nwatson22 Feb 28, 2024
be1754e
Mmove spec_args to SpecOptions
nwatson22 Feb 28, 2024
3103879
Mmove kompile_args to KompileOptions
nwatson22 Feb 28, 2024
d2c0c8d
Construct kdist args with Options classes
nwatson22 Feb 28, 2024
08b3648
Restore logging optinos to kdist
nwatson22 Feb 29, 2024
f124b5a
Add default value
nwatson22 Feb 29, 2024
96a2b6a
Remove default value for save_directory
nwatson22 Feb 29, 2024
c8ab6df
Make default save_directory None
nwatson22 Feb 29, 2024
8da0fdd
Make default spec_module None
nwatson22 Feb 29, 2024
750b59f
Make default spec_module None
nwatson22 Feb 29, 2024
f587319
Add some missing default args
nwatson22 Feb 29, 2024
778bb14
Break off SaveDirOptions
nwatson22 Feb 29, 2024
91469d9
Fix formatting
nwatson22 Feb 29, 2024
df31e79
Merge master into branch
nwatson22 Mar 1, 2024
5abbff6
Merge df31e790cc057104ea60996e7431d622d876f8a6 into 223cd775151e96051…
nwatson22 Mar 1, 2024
085b119
Set Version: 0.1.676
Mar 1, 2024
9f65746
Add Command and CommandHandler classes so commands only have to be li…
nwatson22 Mar 1, 2024
a25f812
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 1, 2024
cc85456
Fix syntax
nwatson22 Mar 4, 2024
56710a8
Merge cc8545668229137a9711e9957754532dd0159968 into 6b710a502a753c6ce…
nwatson22 Mar 4, 2024
a03d77f
Set Version: 0.1.677
Mar 4, 2024
2adbf2d
Move command exec logic into their own classes
nwatson22 Mar 4, 2024
0115983
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 4, 2024
785cd3f
Merge branch 'master' into noah/default-options
nwatson22 Mar 4, 2024
f5a645b
Merge 785cd3fff0352896755bb55ab5f1d6a33a18aa9e into 0cae78f1b06bf2351…
nwatson22 Mar 4, 2024
59e702f
Set Version: 0.1.678
Mar 4, 2024
b4c6a97
Remove default=None, use default() for lists
nwatson22 Mar 4, 2024
274b1ab
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 4, 2024
3e6d404
Fix naming
nwatson22 Mar 4, 2024
5965db2
Merge 3e6d4048a6068583b0933d7fb0a42ff3d8c4a086 into 0cae78f1b06bf2351…
nwatson22 Mar 4, 2024
2f67838
Set Version: 0.1.679
Mar 4, 2024
9d30d23
Rename args to update_args, don't return ArgumentParser when updating
nwatson22 Mar 5, 2024
c43013b
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 5, 2024
322873d
Merge c43013bc09723270b332447c75a2f46a1016e501 into 66c283fc5533f02d9…
nwatson22 Mar 5, 2024
4d61d2f
Set Version: 0.1.680
Mar 5, 2024
ec84092
Fix all_args
nwatson22 Mar 5, 2024
4bd0371
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 5, 2024
3cfcf6b
Remove default values from add_argument in kdist
nwatson22 Mar 5, 2024
181e45e
Fix kdist commands
nwatson22 Mar 5, 2024
b8315cd
Fix typo
nwatson22 Mar 5, 2024
0aac0f2
Use reversed instead of reverse
nwatson22 Mar 5, 2024
7b2628b
Move commands into separate module
nwatson22 Mar 5, 2024
df97fae
Merge branch 'master' into noah/default-options
nwatson22 Mar 5, 2024
662237b
Merge df97faed60a9cc5d973e9c0436a39d537ff1fe92 into 2c9a739d0e20dceb7…
nwatson22 Mar 5, 2024
fdbfc37
Set Version: 0.1.682
Mar 5, 2024
28568a7
Update poetry.lock
nwatson22 Mar 5, 2024
7e084fc
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 5, 2024
2e6885f
Update poetry.lock
nwatson22 Mar 5, 2024
9ed92a8
Add logging options back to top level of kdist
nwatson22 Mar 5, 2024
3ef1561
Merge branch 'master' into noah/default-options
nwatson22 Mar 5, 2024
59191e6
Merge 3ef15613ec77d7d085d4d862e1a94ccf53567379 into 2fa7948dfea1cc7a1…
nwatson22 Mar 5, 2024
6546289
Set Version: 0.1.683
Mar 5, 2024
09b4179
Command is now no longer automatically also an Options, CLI can handl…
nwatson22 Mar 6, 2024
bf66a5d
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 6, 2024
84b8679
Move pyk-specific Commands into separate module
nwatson22 Mar 6, 2024
16d6630
Merge branch 'master' into noah/default-options
nwatson22 Mar 6, 2024
4d29d20
Merge 16d66307fef1236f41d6711ddbe904181af80065 into 03a8ca03c8f93dcc7…
nwatson22 Mar 6, 2024
41ad5e6
Set Version: 0.1.686
Mar 6, 2024
44577de
Fix kdist defaults, fix list defaults always being []
nwatson22 Mar 6, 2024
7e87280
Merge branch 'noah/default-options' of https://github.com/runtimeveri…
nwatson22 Mar 6, 2024
ab7a1a2
Fix no default arg for list
nwatson22 Mar 6, 2024
2f58d50
Fix default not static
nwatson22 Mar 6, 2024
8a02f04
Fix typo
nwatson22 Mar 7, 2024
a5da13f
Update src/pyk/cli/cli.py
nwatson22 Mar 7, 2024
1ac5abc
Add import
nwatson22 Mar 7, 2024
645900d
Switch to using git branch pyk version
nwatson22 Mar 7, 2024
6c0d33d
Merge branch 'master' into noah/default-options
nwatson22 Mar 7, 2024
d32ac85
Merge 6c0d33daf3464541c8683393de69986b5b5e0852 into d876aa15fc33a189b…
nwatson22 Mar 7, 2024
b77481a
Set Version: 0.1.688
Mar 7, 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
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
project = 'pyk'
author = 'Runtime Verification, Inc'
copyright = '2024, Runtime Verification, Inc'
version = '0.1.654'
release = '0.1.654'
version = '0.1.655'
release = '0.1.655'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
2 changes: 1 addition & 1 deletion package/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.654
0.1.655
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "pyk"
version = "0.1.654"
version = "0.1.655"
description = ""
authors = [
"Runtime Verification, Inc. <[email protected]>",
Expand Down
192 changes: 67 additions & 125 deletions src/pyk/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import json
import logging
import sys
from argparse import ArgumentParser, FileType
from enum import Enum
from argparse import ArgumentParser
from pathlib import Path
from typing import TYPE_CHECKING

Expand All @@ -13,7 +12,18 @@
from pyk.kast.inner import KInner
from pyk.kore.rpc import ExecuteResult

from .cli.args import KCLIArgs
from .cli.args import (
CoverageOptions,
GraphImportsOptions,
JsonToKoreOptions,
KoreToJsonOptions,
PrintInput,
PrintOptions,
ProveOptions,
RPCKastOptions,
RPCPrintOptions,
generate_command_options,
)
from .cli.utils import LOG_FORMAT, dir_path, loglevel
from .coverage import get_rule_by_id, strip_coverage_logger
from .cterm import CTerm
Expand All @@ -36,18 +46,12 @@
from .prelude.ml import is_top, mlAnd, mlOr

if TYPE_CHECKING:
from argparse import Namespace
from typing import Any, Final


_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 @@ -57,36 +61,38 @@ def main() -> None:
cli_parser = create_argument_parser()
args = cli_parser.parse_args()

logging.basicConfig(level=loglevel(args), format=LOG_FORMAT)
options = generate_command_options({key: val for (key, val) in vars(args).items() if val is not None})

logging.basicConfig(level=loglevel(options), format=LOG_FORMAT)

executor_name = 'exec_' + args.command.lower().replace('-', '_')
if executor_name not in globals():
raise AssertionError(f'Unimplemented command: {args.command}')

execute = globals()[executor_name]
execute(args)
execute(options)


def exec_print(args: Namespace) -> None:
kompiled_dir: Path = args.definition_dir
def exec_print(options: PrintOptions) -> None:
kompiled_dir: Path = options.definition_dir
printer = KPrint(kompiled_dir)
if args.input == PrintInput.KORE_JSON:
_LOGGER.info(f'Reading Kore JSON from file: {args.term.name}')
kore = Pattern.from_json(args.term.read())
if options.input == PrintInput.KORE_JSON:
_LOGGER.info(f'Reading Kore JSON from file: {options.term.name}')
kore = Pattern.from_json(options.term.read())
term = printer.kore_to_kast(kore)
else:
_LOGGER.info(f'Reading Kast JSON from file: {args.term.name}')
term = KInner.from_json(args.term.read())
_LOGGER.info(f'Reading Kast JSON from file: {options.term.name}')
term = KInner.from_json(options.term.read())
if is_top(term):
args.output_file.write(printer.pretty_print(term))
_LOGGER.info(f'Wrote file: {args.output_file.name}')
options.output_file.write(printer.pretty_print(term))
_LOGGER.info(f'Wrote file: {options.output_file.name}')
else:
if args.minimize:
if args.omit_labels != '' and args.keep_cells != '':
if options.minimize:
if options.omit_labels != None and options.keep_cells != None:
raise ValueError('You cannot use both --omit-labels and --keep-cells.')

abstract_labels = args.omit_labels.split(',') if args.omit_labels != '' else []
keep_cells = args.keep_cells.split(',') if args.keep_cells != '' else []
abstract_labels = options.omit_labels.split(',') if options.omit_labels is not None else []
keep_cells = options.keep_cells.split(',') if options.keep_cells is not None else []
minimized_disjuncts = []

for disjunct in flatten_label('#Or', term):
Expand All @@ -102,14 +108,14 @@ def exec_print(args: Namespace) -> None:
minimized_disjuncts.append(config)
term = propagate_up_constraints(mlOr(minimized_disjuncts, sort=GENERATED_TOP_CELL))

args.output_file.write(printer.pretty_print(term))
_LOGGER.info(f'Wrote file: {args.output_file.name}')
options.output_file.write(printer.pretty_print(term))
_LOGGER.info(f'Wrote file: {options.output_file.name}')


def exec_rpc_print(args: Namespace) -> None:
kompiled_dir: Path = args.definition_dir
def exec_rpc_print(options: RPCPrintOptions) -> None:
kompiled_dir: Path = options.definition_dir
printer = KPrint(kompiled_dir)
input_dict = json.loads(args.input_file.read())
input_dict = json.loads(options.input_file.read())
output_buffer = []

def pretty_print_request(request_params: dict[str, Any]) -> list[str]:
Expand Down Expand Up @@ -178,8 +184,8 @@ def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]:
except KeyError as e:
_LOGGER.critical(f'Could not find key {str(e)} in input JSON file')
exit(1)
if args.output_file is not None:
args.output_file.write('\n'.join(output_buffer))
if options.output_file is not None:
options.output_file.write('\n'.join(output_buffer))
else:
print('\n'.join(output_buffer))
except ValueError as e:
Expand All @@ -188,13 +194,13 @@ def pretty_print_execute_response(execute_result: ExecuteResult) -> list[str]:
exit(1)


def exec_rpc_kast(args: Namespace) -> None:
def exec_rpc_kast(options: RPCKastOptions) -> None:
"""
Convert an 'execute' JSON RPC response to a new 'execute' or 'simplify' request,
copying parameters from a reference request.
"""
reference_request = json.loads(args.reference_request_file.read())
input_dict = json.loads(args.response_file.read())
reference_request = json.loads(options.reference_request_file.read())
input_dict = json.loads(options.response_file.read())
execute_result = ExecuteResult.from_dict(input_dict['result'])
non_state_keys = set(reference_request['params'].keys()).difference(['state'])
request_params = {}
Expand All @@ -207,19 +213,19 @@ def exec_rpc_kast(args: Namespace) -> None:
'method': reference_request['method'],
'params': request_params,
}
args.output_file.write(json.dumps(request))
options.output_file.write(json.dumps(request))


def exec_prove(args: Namespace) -> None:
kompiled_dir: Path = args.definition_dir
kprover = KProve(kompiled_dir, args.main_file)
final_state = kprover.prove(Path(args.spec_file), spec_module_name=args.spec_module, args=args.kArgs)
args.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict()))
_LOGGER.info(f'Wrote file: {args.output_file.name}')
def exec_prove(options: ProveOptions) -> None:
kompiled_dir: Path = options.definition_dir
kprover = KProve(kompiled_dir, options.main_file)
final_state = kprover.prove(Path(options.spec_file), spec_module_name=options.spec_module, args=options.k_args)
options.output_file.write(json.dumps(mlOr([state.kast for state in final_state]).to_dict()))
_LOGGER.info(f'Wrote file: {options.output_file.name}')


def exec_graph_imports(args: Namespace) -> None:
kompiled_dir: Path = args.definition_dir
def exec_graph_imports(options: GraphImportsOptions) -> None:
kompiled_dir: Path = options.definition_dir
kprinter = KPrint(kompiled_dir)
definition = kprinter.definition
import_graph = Digraph()
Expand All @@ -233,111 +239,47 @@ def exec_graph_imports(args: Namespace) -> None:
_LOGGER.info(f'Wrote file: {graph_file}')


def exec_coverage(args: Namespace) -> None:
kompiled_dir: Path = args.definition_dir
def exec_coverage(options: CoverageOptions) -> None:
kompiled_dir: Path = options.definition_dir
definition = remove_source_map(read_kast_definition(kompiled_dir / 'compiled.json'))
pretty_printer = PrettyPrinter(definition)
for rid in args.coverage_file:
for rid in options.coverage_file:
rule = minimize_rule(strip_coverage_logger(get_rule_by_id(definition, rid.strip())))
args.output.write('\n\n')
args.output.write('Rule: ' + rid.strip())
args.output.write('\nUnparsed:\n')
args.output.write(pretty_printer.print(rule))
_LOGGER.info(f'Wrote file: {args.output.name}')
options.output_file.write('\n\n')
options.output_file.write('Rule: ' + rid.strip())
options.output_file.write('\nUnparsed:\n')
options.output_file.write(pretty_printer.print(rule))
_LOGGER.info(f'Wrote file: {options.output_file.name}')


def exec_kore_to_json(args: Namespace) -> None:
def exec_kore_to_json(options: KoreToJsonOptions) -> None:
text = sys.stdin.read()
kore = KoreParser(text).pattern()
print(kore.json)


def exec_json_to_kore(args: dict[str, Any]) -> None:
def exec_json_to_kore(options: JsonToKoreOptions) -> None:
text = sys.stdin.read()
kore = Pattern.from_json(text)
kore.write(sys.stdout)
sys.stdout.write('\n')


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

definition_args = ArgumentParser(add_help=False)
definition_args.add_argument('definition_dir', type=dir_path, help='Path to definition directory.')

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, definition_args, k_cli_args.display_args],
)
print_args.add_argument('term', type=FileType('r'), help='Input term (in format specified with --input).')
print_args.add_argument('--input', default=PrintInput.KAST_JSON, type=PrintInput, choices=list(PrintInput))
print_args.add_argument('--omit-labels', default='', nargs='?', help='List of labels to omit from output.')
print_args.add_argument(
'--keep-cells', default='', nargs='?', help='List of cells with primitive values to keep in output.'
)
print_args.add_argument('--output-file', type=FileType('w'), default='-')

rpc_print_args = pyk_args_command.add_parser(
'rpc-print',
help='Pretty-print an RPC request/response',
parents=[k_cli_args.logging_args, definition_args],
)
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'), default='-')

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'), default='-')

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

pyk_args_command.add_parser(
'graph-imports',
help='Graph the imports of a given definition.',
parents=[k_cli_args.logging_args, definition_args],
)

coverage_args = pyk_args_command.add_parser(
'coverage',
help='Convert coverage file to human readable log.',
parents=[k_cli_args.logging_args, definition_args],
)
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'), default='-')

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])
pyk_args_command = PrintOptions.parser(pyk_args_command)
pyk_args_command = RPCPrintOptions.parser(pyk_args_command)
pyk_args_command = RPCKastOptions.parser(pyk_args_command)
pyk_args_command = ProveOptions.parser(pyk_args_command)
pyk_args_command = GraphImportsOptions.parser(pyk_args_command)
pyk_args_command = CoverageOptions.parser(pyk_args_command)
pyk_args_command = KoreToJsonOptions.parser(pyk_args_command)
pyk_args_command = JsonToKoreOptions.parser(pyk_args_command)

return pyk_args

Expand Down
Loading
Loading