From af84b14e9fd24726d9c1acb9609054d5fced0bd5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 08:29:18 +0000 Subject: [PATCH 1/6] Initial plan From 89c162f1b3d553c68bffd14cead296d26287a1fd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 08:32:28 +0000 Subject: [PATCH 2/6] Add comprehensive BNF README and Support Packages section to main README Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com> --- README.md | 39 ++++++ bnf/README.md | 380 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 416 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cffd282..f8b8875 100644 --- a/README.md +++ b/README.md @@ -344,6 +344,45 @@ Example programs are provided in the `examples/` directory: Each example demonstrates logical inference using propositional logic axioms. +## Support Packages + +The DS project includes additional support packages that extend functionality: + +### BNF Conversion Library + +Located in the `/bnf` directory, this package provides bidirectional conversion between DS syntax formats: + +- **apyds-bnf** (Python): [PyPI](https://pypi.org/project/apyds-bnf/) +- **atsds-bnf** (JavaScript): [npm](https://www.npmjs.com/package/atsds-bnf) + +The BNF library converts between: +- **Ds format**: S-expression (lisp-like) syntax used internally by DS +- **Dsp format**: Traditional, human-readable syntax with infix operators + +This makes it easier to write logical rules in a natural mathematical notation and convert them to/from the DS internal format. + +**Installation:** +```bash +# Python +pip install apyds-bnf + +# JavaScript +npm install atsds-bnf +``` + +**Quick example:** +```python +from apyds_bnf import parse, unparse + +# Convert readable syntax to DS format +parse("a, b -> c") # Returns: "a\nb\n----\nc" + +# Convert DS format to readable syntax +unparse("a\nb\n----\nc") # Returns: "a, b -> c" +``` + +For more details, see the [BNF package README](/bnf/README.md). + ## Development ### Code Formatting diff --git a/bnf/README.md b/bnf/README.md index 62a48fa..b2611bf 100644 --- a/bnf/README.md +++ b/bnf/README.md @@ -1,6 +1,380 @@ # BNF Support Package for DS -This package provides bidirectional conversion between two syntax formats for the DS deductive system: +A bidirectional conversion library for the DS deductive system, providing seamless translation between two syntax formats: -- **Ds**: The lisp-like syntax currently used in DS -- **Dsp**: A traditional readable syntax with infix operators +- **Ds**: The S-expression (lisp-like) syntax used internally by DS +- **Dsp**: A traditional, human-readable syntax with infix operators + +This package enables you to write logical rules in a more natural, mathematical notation and convert them to the DS internal format, or vice versa. + +## Features + +- **Bidirectional Conversion**: Convert between Ds and Dsp syntax formats +- **Multi-Language Support**: Available for both Python and JavaScript/TypeScript +- **Parse**: Convert from readable Dsp syntax to DS internal format +- **Unparse**: Convert from DS internal format to readable Dsp syntax +- **Comprehensive Operator Support**: Functions, subscripts, unary and binary operators +- **ANTLR-Based**: Built on ANTLR 4.13.2 for robust parsing + +## Installation + +### Python (pip) + +```bash +pip install apyds-bnf +``` + +Requires Python 3.10-3.14. + +### JavaScript/TypeScript (npm) + +```bash +npm install atsds-bnf +``` + +## Quick Start + +### Python Example + +```python +from apyds_bnf import parse, unparse + +# Parse: Convert from readable Dsp to DS format +dsp_input = "a, b -> c" +ds_output = parse(dsp_input) +print(ds_output) +# Output: +# a +# b +# ---- +# c + +# Unparse: Convert from DS format to readable Dsp +ds_input = "a\nb\n----\nc" +dsp_output = unparse(ds_input) +print(dsp_output) +# Output: a, b -> c +``` + +### JavaScript Example + +```javascript +import { parse, unparse } from "atsds-bnf"; + +// Parse: Convert from readable Dsp to DS format +const dsp_input = "a, b -> c"; +const ds_output = parse(dsp_input); +console.log(ds_output); +// Output: +// a +// b +// ---- +// c + +// Unparse: Convert from DS format to readable Dsp +const ds_input = "a\nb\n----\nc"; +const dsp_output = unparse(ds_input); +console.log(dsp_output); +// Output: a, b -> c +``` + +## Syntax Formats + +### Ds Format (Internal) + +The Ds format uses S-expressions (lisp-like syntax) for representing logical rules: + +``` +premise1 +premise2 +---------- +conclusion +``` + +For structured terms: +- Functions: `(function f a b)` +- Subscripts: `(subscript a i j)` +- Binary operators: `(binary + a b)` +- Unary operators: `(unary ~ a)` + +### Dsp Format (Human-Readable) + +The Dsp format uses traditional mathematical notation: + +``` +premise1, premise2 -> conclusion +``` + +For structured terms: +- Functions: `f(a, b)` +- Subscripts: `a[i, j]` +- Binary operators: `a + b` +- Unary operators: `~ a` + +### Syntax Comparison Table + +| Description | Dsp Format (Input) | Ds Format (Output) | +|-------------|-------------------|-------------------| +| Simple rule | `a, b -> c` | `a\nb\n----\nc` | +| Axiom (no premises) | `a` | `----\na` | +| Function call | `f(a, b) -> c` | `(function f a b)\n----------------\nc` | +| Subscript | `a[i, j] -> b` | `(subscript a i j)\n-----------------\nb` | +| Binary operator | `(a + b) -> c` | `(binary + a b)\n--------------\nc` | +| Unary operator | `~ a -> b` | `(unary ~ a)\n-----------\nb` | +| Complex expression | `(a + b) * c, d[i] -> f(g, h)` | `(binary * (binary + a b) c)\n(subscript d i)\n---------------------------\n(function f g h)` | + +## API Reference + +### Python + +#### `parse(dsp_text: str) -> str` + +Converts Dsp syntax to Ds syntax. + +**Parameters:** +- `dsp_text`: String in Dsp format (human-readable syntax) + +**Returns:** +- String in Ds format (S-expression syntax) + +**Example:** +```python +from apyds_bnf import parse + +result = parse("a, b -> c") +# Returns: "a\nb\n----\nc" +``` + +#### `unparse(ds_text: str) -> str` + +Converts Ds syntax to Dsp syntax. + +**Parameters:** +- `ds_text`: String in Ds format (S-expression syntax) + +**Returns:** +- String in Dsp format (human-readable syntax) + +**Example:** +```python +from apyds_bnf import unparse + +result = unparse("a\nb\n----\nc") +# Returns: "a, b -> c" +``` + +### JavaScript + +#### `parse(dspText: string): string` + +Converts Dsp syntax to Ds syntax. + +**Parameters:** +- `dspText`: String in Dsp format (human-readable syntax) + +**Returns:** +- String in Ds format (S-expression syntax) + +**Example:** +```javascript +import { parse } from "atsds-bnf"; + +const result = parse("a, b -> c"); +// Returns: "a\nb\n----\nc" +``` + +#### `unparse(dsText: string): string` + +Converts Ds syntax to Dsp syntax. + +**Parameters:** +- `dsText`: String in Ds format (S-expression syntax) + +**Returns:** +- String in Dsp format (human-readable syntax) + +**Example:** +```javascript +import { unparse } from "atsds-bnf"; + +const result = unparse("a\nb\n----\nc"); +// Returns: "a, b -> c" +``` + +## Examples + +### Parsing Complex Expressions + +```python +from apyds_bnf import parse + +# Parse a complex expression with nested operators +dsp = "(a + b) * c, d[i] -> f(g, h)" +ds = parse(dsp) +print(ds) +# Output: +# (binary * (binary + a b) c) +# (subscript d i) +# --------------------------- +# (function f g h) +``` + +### Unparsing Multiple Rules + +```python +from apyds_bnf import unparse + +# Unparse multiple rules +ds = """a +---- +b + +c +---- +d""" +dsp = unparse(ds) +print(dsp) +# Output: +# a -> b +# c -> d +``` + +### Round-trip Conversion + +```python +from apyds_bnf import parse, unparse + +# Original Dsp format +original = "a, b -> c" + +# Convert to Ds and back to Dsp +ds_format = parse(original) +result = unparse(ds_format) + +assert result == original # True +``` + +## Building from Source + +### Prerequisites + +- Python 3.10-3.14 (for Python package) +- Node.js (for JavaScript package) +- Java (for ANTLR parser generation) +- ANTLR 4.13.2 + +### Python Package + +```bash +cd bnf + +# Install dependencies +uv sync --extra dev + +# Generate ANTLR parsers (done automatically during build) +# Build package +uv build + +# Run tests +pytest + +# Run with coverage +pytest --cov +``` + +### JavaScript Package + +```bash +cd bnf + +# Install dependencies +npm install + +# Generate ANTLR parsers and build +npm run build + +# Run tests +npm test +``` + +## Testing + +The package includes comprehensive tests for both Python and JavaScript implementations. + +### Python Tests + +Located in `tests/test_parse_unparse.py`: + +```bash +cd bnf +pytest +``` + +Tests cover: +- Simple rules with premises and conclusions +- Axioms (rules with no premises) +- Function calls +- Subscript notation +- Binary and unary operators +- Multiple rules +- Complex nested expressions +- Round-trip conversions + +### JavaScript Tests + +Located in `tests/test_parse_unparse.mjs`: + +```bash +cd bnf +npm test +``` + +Same test coverage as Python implementation. + +## Grammar Files + +The conversion is based on ANTLR grammars: + +- **Ds.g4**: Grammar for the Ds format (S-expression syntax) +- **Dsp.g4**: Grammar for the Dsp format (human-readable syntax) + +These grammars are used to generate parsers for both Python and JavaScript. + +## Development + +### Generating ANTLR Parsers + +For Python: +```bash +java -jar antlr-4.13.2-complete.jar -Dlanguage=Python3 Ds.g4 -visitor -no-listener -o apyds_bnf +java -jar antlr-4.13.2-complete.jar -Dlanguage=Python3 Dsp.g4 -visitor -no-listener -o apyds_bnf +``` + +For JavaScript: +```bash +antlr4 -Dlanguage=JavaScript Ds.g4 -visitor -no-listener -o atsds_bnf +antlr4 -Dlanguage=JavaScript Dsp.g4 -visitor -no-listener -o atsds_bnf +``` + +### Code Formatting + +- Python: Uses `ruff` for linting and formatting (configured in `pyproject.toml`) +- JavaScript: Standard npm formatting tools + +## License + +This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). + +## Repository + +- **GitHub**: [USTC-KnowledgeComputingLab/ds](https://github.com/USTC-KnowledgeComputingLab/ds) (in `/bnf` directory) +- **Python Package**: [apyds-bnf](https://pypi.org/project/apyds-bnf/) +- **npm Package**: [atsds-bnf](https://www.npmjs.com/package/atsds-bnf) + +## Author + +Hao Zhang + +## Related + +This package is a support library for the [DS (Deductive System)](https://github.com/USTC-KnowledgeComputingLab/ds) project. For the main DS library with C++ core and bindings, see the [main repository](https://github.com/USTC-KnowledgeComputingLab/ds). From 1b7ac6cc9cbaa1b9d24b9402d5b9b8dbad559d9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 08:34:19 +0000 Subject: [PATCH 3/6] Fix BNF README to match actual parse/unparse behavior from tests Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com> --- bnf/README.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/bnf/README.md b/bnf/README.md index b2611bf..f28c5cf 100644 --- a/bnf/README.md +++ b/bnf/README.md @@ -108,20 +108,22 @@ premise1, premise2 -> conclusion For structured terms: - Functions: `f(a, b)` - Subscripts: `a[i, j]` -- Binary operators: `a + b` -- Unary operators: `~ a` +- Binary operators: `(a + b)` (parenthesized) +- Unary operators: `(~ a)` (parenthesized) ### Syntax Comparison Table -| Description | Dsp Format (Input) | Ds Format (Output) | +| Description | Dsp Format (parse input / unparse output) | Ds Format | |-------------|-------------------|-------------------| | Simple rule | `a, b -> c` | `a\nb\n----\nc` | -| Axiom (no premises) | `a` | `----\na` | +| Axiom (parse input) | `a` | `----\na` | +| Axiom (unparse output) | ` -> a` | `----\na` | | Function call | `f(a, b) -> c` | `(function f a b)\n----------------\nc` | | Subscript | `a[i, j] -> b` | `(subscript a i j)\n-----------------\nb` | | Binary operator | `(a + b) -> c` | `(binary + a b)\n--------------\nc` | -| Unary operator | `~ a -> b` | `(unary ~ a)\n-----------\nb` | -| Complex expression | `(a + b) * c, d[i] -> f(g, h)` | `(binary * (binary + a b) c)\n(subscript d i)\n---------------------------\n(function f g h)` | +| Unary operator (parse input) | `~ a -> b` | `(unary ~ a)\n-----------\nb` | +| Unary operator (unparse output) | `(~ a) -> b` | `(unary ~ a)\n-----------\nb` | +| Complex expression | `((a + b) * c), d[i] -> f(g, h)` | `(binary * (binary + a b) c)\n(subscript d i)\n---------------------------\n(function f g h)` | ## API Reference @@ -225,18 +227,11 @@ print(ds) from apyds_bnf import unparse # Unparse multiple rules -ds = """a ----- -b - -c ----- -d""" +ds = "a\n----\nb\n\nc\n----\nd" dsp = unparse(ds) print(dsp) -# Output: -# a -> b -# c -> d +# Output: a -> b +# c -> d ``` ### Round-trip Conversion From 7e1ef151df7b53efb6783a079f89bf0182750794 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 9 Dec 2025 08:41:09 +0000 Subject: [PATCH 4/6] Simplify documentation per feedback: condense Support Packages section and remove API Reference, Examples, Testing, and Development sections Co-authored-by: hzhangxyz <11623447+hzhangxyz@users.noreply.github.com> --- README.md | 37 +---------- bnf/README.md | 179 -------------------------------------------------- 2 files changed, 1 insertion(+), 215 deletions(-) diff --git a/README.md b/README.md index f8b8875..73bf4ef 100644 --- a/README.md +++ b/README.md @@ -346,42 +346,7 @@ Each example demonstrates logical inference using propositional logic axioms. ## Support Packages -The DS project includes additional support packages that extend functionality: - -### BNF Conversion Library - -Located in the `/bnf` directory, this package provides bidirectional conversion between DS syntax formats: - -- **apyds-bnf** (Python): [PyPI](https://pypi.org/project/apyds-bnf/) -- **atsds-bnf** (JavaScript): [npm](https://www.npmjs.com/package/atsds-bnf) - -The BNF library converts between: -- **Ds format**: S-expression (lisp-like) syntax used internally by DS -- **Dsp format**: Traditional, human-readable syntax with infix operators - -This makes it easier to write logical rules in a natural mathematical notation and convert them to/from the DS internal format. - -**Installation:** -```bash -# Python -pip install apyds-bnf - -# JavaScript -npm install atsds-bnf -``` - -**Quick example:** -```python -from apyds_bnf import parse, unparse - -# Convert readable syntax to DS format -parse("a, b -> c") # Returns: "a\nb\n----\nc" - -# Convert DS format to readable syntax -unparse("a\nb\n----\nc") # Returns: "a, b -> c" -``` - -For more details, see the [BNF package README](/bnf/README.md). +- **BNF Conversion Library** ([apyds-bnf](https://pypi.org/project/apyds-bnf/), [atsds-bnf](https://www.npmjs.com/package/atsds-bnf)): Bidirectional conversion between DS syntax formats. See [/bnf](/bnf) for details. ## Development diff --git a/bnf/README.md b/bnf/README.md index f28c5cf..ab33243 100644 --- a/bnf/README.md +++ b/bnf/README.md @@ -125,130 +125,6 @@ For structured terms: | Unary operator (unparse output) | `(~ a) -> b` | `(unary ~ a)\n-----------\nb` | | Complex expression | `((a + b) * c), d[i] -> f(g, h)` | `(binary * (binary + a b) c)\n(subscript d i)\n---------------------------\n(function f g h)` | -## API Reference - -### Python - -#### `parse(dsp_text: str) -> str` - -Converts Dsp syntax to Ds syntax. - -**Parameters:** -- `dsp_text`: String in Dsp format (human-readable syntax) - -**Returns:** -- String in Ds format (S-expression syntax) - -**Example:** -```python -from apyds_bnf import parse - -result = parse("a, b -> c") -# Returns: "a\nb\n----\nc" -``` - -#### `unparse(ds_text: str) -> str` - -Converts Ds syntax to Dsp syntax. - -**Parameters:** -- `ds_text`: String in Ds format (S-expression syntax) - -**Returns:** -- String in Dsp format (human-readable syntax) - -**Example:** -```python -from apyds_bnf import unparse - -result = unparse("a\nb\n----\nc") -# Returns: "a, b -> c" -``` - -### JavaScript - -#### `parse(dspText: string): string` - -Converts Dsp syntax to Ds syntax. - -**Parameters:** -- `dspText`: String in Dsp format (human-readable syntax) - -**Returns:** -- String in Ds format (S-expression syntax) - -**Example:** -```javascript -import { parse } from "atsds-bnf"; - -const result = parse("a, b -> c"); -// Returns: "a\nb\n----\nc" -``` - -#### `unparse(dsText: string): string` - -Converts Ds syntax to Dsp syntax. - -**Parameters:** -- `dsText`: String in Ds format (S-expression syntax) - -**Returns:** -- String in Dsp format (human-readable syntax) - -**Example:** -```javascript -import { unparse } from "atsds-bnf"; - -const result = unparse("a\nb\n----\nc"); -// Returns: "a, b -> c" -``` - -## Examples - -### Parsing Complex Expressions - -```python -from apyds_bnf import parse - -# Parse a complex expression with nested operators -dsp = "(a + b) * c, d[i] -> f(g, h)" -ds = parse(dsp) -print(ds) -# Output: -# (binary * (binary + a b) c) -# (subscript d i) -# --------------------------- -# (function f g h) -``` - -### Unparsing Multiple Rules - -```python -from apyds_bnf import unparse - -# Unparse multiple rules -ds = "a\n----\nb\n\nc\n----\nd" -dsp = unparse(ds) -print(dsp) -# Output: a -> b -# c -> d -``` - -### Round-trip Conversion - -```python -from apyds_bnf import parse, unparse - -# Original Dsp format -original = "a, b -> c" - -# Convert to Ds and back to Dsp -ds_format = parse(original) -result = unparse(ds_format) - -assert result == original # True -``` - ## Building from Source ### Prerequisites @@ -292,40 +168,6 @@ npm run build npm test ``` -## Testing - -The package includes comprehensive tests for both Python and JavaScript implementations. - -### Python Tests - -Located in `tests/test_parse_unparse.py`: - -```bash -cd bnf -pytest -``` - -Tests cover: -- Simple rules with premises and conclusions -- Axioms (rules with no premises) -- Function calls -- Subscript notation -- Binary and unary operators -- Multiple rules -- Complex nested expressions -- Round-trip conversions - -### JavaScript Tests - -Located in `tests/test_parse_unparse.mjs`: - -```bash -cd bnf -npm test -``` - -Same test coverage as Python implementation. - ## Grammar Files The conversion is based on ANTLR grammars: @@ -335,27 +177,6 @@ The conversion is based on ANTLR grammars: These grammars are used to generate parsers for both Python and JavaScript. -## Development - -### Generating ANTLR Parsers - -For Python: -```bash -java -jar antlr-4.13.2-complete.jar -Dlanguage=Python3 Ds.g4 -visitor -no-listener -o apyds_bnf -java -jar antlr-4.13.2-complete.jar -Dlanguage=Python3 Dsp.g4 -visitor -no-listener -o apyds_bnf -``` - -For JavaScript: -```bash -antlr4 -Dlanguage=JavaScript Ds.g4 -visitor -no-listener -o atsds_bnf -antlr4 -Dlanguage=JavaScript Dsp.g4 -visitor -no-listener -o atsds_bnf -``` - -### Code Formatting - -- Python: Uses `ruff` for linting and formatting (configured in `pyproject.toml`) -- JavaScript: Standard npm formatting tools - ## License This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). From 76a80a3e9a094638a6b7e98f33639da9b081d292 Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Tue, 9 Dec 2025 17:25:11 +0800 Subject: [PATCH 5/6] Fix some issues. --- bnf/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bnf/README.md b/bnf/README.md index ab33243..7fcd3c9 100644 --- a/bnf/README.md +++ b/bnf/README.md @@ -116,13 +116,11 @@ For structured terms: | Description | Dsp Format (parse input / unparse output) | Ds Format | |-------------|-------------------|-------------------| | Simple rule | `a, b -> c` | `a\nb\n----\nc` | -| Axiom (parse input) | `a` | `----\na` | -| Axiom (unparse output) | ` -> a` | `----\na` | +| Axiom | `a` | `----\na` | | Function call | `f(a, b) -> c` | `(function f a b)\n----------------\nc` | | Subscript | `a[i, j] -> b` | `(subscript a i j)\n-----------------\nb` | | Binary operator | `(a + b) -> c` | `(binary + a b)\n--------------\nc` | -| Unary operator (parse input) | `~ a -> b` | `(unary ~ a)\n-----------\nb` | -| Unary operator (unparse output) | `(~ a) -> b` | `(unary ~ a)\n-----------\nb` | +| Unary operator | `~ a -> b` | `(unary ~ a)\n-----------\nb` | | Complex expression | `((a + b) * c), d[i] -> f(g, h)` | `(binary * (binary + a b) c)\n(subscript d i)\n---------------------------\n(function f g h)` | ## Building from Source From ea07ada1245a088df1705ce8a7e7508a47ce28bf Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Tue, 9 Dec 2025 17:26:37 +0800 Subject: [PATCH 6/6] Fix some mistakes. --- bnf/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bnf/README.md b/bnf/README.md index 7fcd3c9..ce4af3c 100644 --- a/bnf/README.md +++ b/bnf/README.md @@ -140,7 +140,6 @@ cd bnf # Install dependencies uv sync --extra dev -# Generate ANTLR parsers (done automatically during build) # Build package uv build @@ -159,7 +158,7 @@ cd bnf # Install dependencies npm install -# Generate ANTLR parsers and build +# Build package npm run build # Run tests