-
Notifications
You must be signed in to change notification settings - Fork 126
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
Feat/expose database predicates #812
Conversation
WalkthroughThis pull request introduces three new feature files for testing Prolog predicates: Changes
Possibly related PRs
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Codecov ReportAttention: Patch coverage is
@@ Coverage Diff @@
## main #812 +/- ##
==========================================
- Coverage 42.73% 42.68% -0.06%
==========================================
Files 111 112 +1
Lines 6273 6281 +8
==========================================
Hits 2681 2681
- Misses 3468 3476 +8
Partials 124 124
|
3176383
to
0d4282c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (8)
x/logic/predicate/database.go (1)
1-52
: Consider introducing an interface for better testabilityThe current implementation is tightly coupled with the engine package. Consider introducing an interface for the database operations, which would:
- Make the code more testable through mocking
- Provide clearer contracts for the operations
- Allow for different implementations in the future
Example interface:
type DatabasePredicates interface { Asserta(clause engine.Term) error Assertz(clause engine.Term) error Retract(clause engine.Term) error Abolish(indicator engine.Term) error }🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 13-14: x/logic/predicate/database.go#L13-L14
Added lines #L13 - L14 were not covered by tests
[warning] 25-26: x/logic/predicate/database.go#L25-L26
Added lines #L25 - L26 were not covered by tests
[warning] 37-38: x/logic/predicate/database.go#L37-L38
Added lines #L37 - L38 were not covered by tests
[warning] 50-51: x/logic/predicate/database.go#L50-L51
Added lines #L50 - L51 were not covered by testsx/logic/keeper/features/retract_1.feature (3)
1-3
: Enhance the feature description with more context.The current description is quite brief. Consider expanding it to provide more context about the
retract/1
predicate's purpose, usage, and relationship with dynamic predicates.Feature: retract/1 - This feature is to test the retract/1 predicate. + The retract/1 predicate is used to remove facts or clauses from the Prolog database + during runtime. It is a fundamental predicate for managing dynamic predicates, + allowing the modification of the knowledge base during program execution. + + This feature tests the functionality and constraints of retract/1, + particularly its interaction with dynamic and static predicates.
4-24
: Enhance test coverage with intermediate state verification.While the scenario demonstrates basic retraction, it could be more comprehensive:
- Add a step to verify the fact was successfully asserted before retraction
- Include multiple facts to test selective retraction
- Document the expected gas usage rationale
Consider expanding the scenario like this:
Given the query: """ prolog - assertz(parent(john, alice)), retract(parent(john, alice)), parent(X, Y). + assertz(parent(john, alice)), + assertz(parent(mary, bob)), + parent(X, Y), % Verify facts were asserted + retract(parent(john, alice)), + parent(X, Y). % Verify selective retraction """
26-48
: Add information about declaring dynamic predicates.The scenario effectively demonstrates the static predicate constraint. Consider enhancing the documentation to show how predicates can be properly declared as dynamic.
This scenario demonstrates that only dynamic predicates can be retracted. In Prolog, dynamic predicates are those that can be modified during runtime. This is in contrast to static predicates, which are fixed and cannot be modified. + + To make a predicate dynamic, it must be declared using the dynamic/1 directive: + :- dynamic parent/2.x/logic/keeper/features/assertz_1.feature (2)
78-78
: Consider documenting the solution limit rationale.While limiting to 2 solutions is appropriate here, it would be helpful to document why this limit was chosen to prevent future confusion.
- When the query is run (limited to 2 solutions) + When the query is run (limited to 2 solutions to demonstrate ordering)
95-127
: Consider adding error handling scenarios for inventory management.While the happy path is well tested, consider adding scenarios for:
- Removing non-existent items
- Adding duplicate items (if that should be prevented)
- Adding invalid item types
Example addition:
Scenario: Handle removal of non-existent inventory items Given the program: """ prolog :- dynamic(inventory/1). add_item(Item) :- assertz(inventory(Item)). remove_item(Item) :- (inventory(Item) -> retract(inventory(Item)) ; throw(error(non_existent_item(Item), remove_item/1)) ). """ And the query: """ prolog remove_item('non_existent_item'). """ When the query is run Then expect an error for non-existent itemx/logic/keeper/features/asserta_1.feature (2)
1-3
: Enhance feature documentation with ISO standard reference and usage details.Consider expanding the feature description to include:
- Reference to the ISO/IEC 13211-1:1995 standard
- Clear explanation of how
asserta/1
differs fromassertz/1
- Common use cases and limitations
Feature: asserta/1 - This feature is to test the asserta/1 predicate. + This feature tests the asserta/1 predicate, which is defined in ISO/IEC 13211-1:1995. + + The asserta/1 predicate adds a new clause at the beginning of a dynamic procedure, + in contrast to assertz/1 which adds it at the end. This affects the order in which + clauses are matched during queries. + + Common uses include: + - Maintaining ordered fact databases + - Implementing priority-based systems + - Dynamic knowledge base updates
35-57
: Consider adding a positive test case for dynamic predicate declaration.While the current scenario effectively demonstrates the error case, consider adding a complementary test showing the correct way to declare and assert a dynamic predicate. This would provide a complete example of both what works and what doesn't.
parent(jane, alice). + +% Add positive test case +:- dynamic(dynamic_parent/2). +dynamic_parent(jane, alice). +asserta(dynamic_parent(john, alice)). % This should succeed
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (32)
docs/predicate/abolish_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/asserta_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/assertz_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/atomic_list_concat_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/atomic_list_concat_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/bank_balances_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/bank_locked_balances_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/bank_spendable_balances_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/bech32_address_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/block_height_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/block_time_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/chain_id_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/consult_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/crypto_data_hash_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/current_output_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/did_components_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/ecdsa_verify_4.md
is excluded by!docs/predicate/**/*.md
docs/predicate/eddsa_verify_4.md
is excluded by!docs/predicate/**/*.md
docs/predicate/hex_bytes_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/json_prolog_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/json_read_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/json_write_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/open_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/open_4.md
is excluded by!docs/predicate/**/*.md
docs/predicate/read_string_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/read_term_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/retract_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/source_file_1.md
is excluded by!docs/predicate/**/*.md
docs/predicate/string_bytes_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/term_to_atom_2.md
is excluded by!docs/predicate/**/*.md
docs/predicate/uri_encoded_3.md
is excluded by!docs/predicate/**/*.md
docs/predicate/write_term_3.md
is excluded by!docs/predicate/**/*.md
📒 Files selected for processing (4)
x/logic/keeper/features/asserta_1.feature
(1 hunks)x/logic/keeper/features/assertz_1.feature
(1 hunks)x/logic/keeper/features/retract_1.feature
(1 hunks)x/logic/predicate/database.go
(1 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
x/logic/predicate/database.go
[warning] 13-14: x/logic/predicate/database.go#L13-L14
Added lines #L13 - L14 were not covered by tests
[warning] 25-26: x/logic/predicate/database.go#L25-L26
Added lines #L25 - L26 were not covered by tests
[warning] 37-38: x/logic/predicate/database.go#L37-L38
Added lines #L37 - L38 were not covered by tests
[warning] 50-51: x/logic/predicate/database.go#L50-L51
Added lines #L50 - L51 were not covered by tests
🔇 Additional comments (12)
x/logic/predicate/database.go (5)
1-3
: LGTM: Package structure is clean and focused
The package name and import align well with the implementation purpose.
41-52
:
Consider adding safety checks for system predicates
The Abolish operation is potentially dangerous if used on system predicates. Consider adding validation to prevent removal of critical predicates.
#!/bin/bash
# Look for any existing predicate protection mechanisms
rg "system.*predicate" -A 5
# Check for any validation in the engine implementation
ast-grep --pattern 'func Abolish($_, $_, $_, $_) {
$$$
if ($$$) {
$$$
}
$$$
}'
Suggested implementation:
func Abolish(vm *engine.VM, indicator engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise {
// Add validation for system predicates
if isSystemPredicate(indicator) {
return engine.Error("cannot abolish system predicate")
}
return engine.Abolish(vm, indicator, cont, env)
}
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 50-51: x/logic/predicate/database.go#L50-L51
Added lines #L50 - L51 were not covered by tests
17-27
: Documentation follows established pattern
The documentation maintains consistency with Asserta implementation.
Add test coverage for Assertz implementation
Similar to Asserta, this function requires unit test coverage to verify its behavior in various scenarios.
#!/bin/bash
# Look for any existing test cases for Assertz
rg -l "TestAssertz"
# Check if there are any existing examples or usage patterns
rg "Assertz\(" -A 3
Would you like me to help generate unit tests for this function?
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 25-26: x/logic/predicate/database.go#L25-L26
Added lines #L25 - L26 were not covered by tests
5-15
: Documentation is clear and comprehensive
The function signature and parameter descriptions are well documented.
Add test coverage for Asserta implementation
The function lacks test coverage according to static analysis. While feature files exist, unit tests would help verify edge cases.
#!/bin/bash
# Check for existing test files
fd "database_test.go" --type f
# Look for any existing test cases for Asserta
rg -l "TestAsserta"
Would you like me to help generate unit tests for this function?
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 13-14: x/logic/predicate/database.go#L13-L14
Added lines #L13 - L14 were not covered by tests
29-39
: Verify error handling for non-existent clauses
While the implementation is clean, we should ensure proper error handling when attempting to retract non-existent clauses.
Would you like me to help implement error handling tests?
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 37-38: x/logic/predicate/database.go#L37-L38
Added lines #L37 - L38 were not covered by tests
x/logic/keeper/features/retract_1.feature (1)
1-48
: Verify database predicate implementation against ISO standard.
The implementation appears to follow standard Prolog behavior, but we should verify it matches the ISO Prolog standard for database predicates.
✅ Verification successful
Let me gather more information about the implementation details of these database predicates to verify ISO compliance.
Database predicates implementation verified as ISO Prolog compliant
The implementation correctly follows ISO Prolog standard for database predicates:
- Proper permission error handling for static procedures
- Correct behavior for asserta/1 (beginning) and assertz/1 (end) insertion
- Standard retract/1 behavior for removing facts
- Dynamic predicate declaration requirement enforced
- Expected error messages format matches ISO specification
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other database predicate implementations to ensure consistency
rg -g '*.feature' -A 5 'Feature: (?:assert[az]/1|retract/1|abolish/[12]|clause/[23])'
Length of output: 1652
Script:
#!/bin/bash
# Check the actual test scenarios and error handling in database predicate features
cat x/logic/keeper/features/asserta_1.feature x/logic/keeper/features/assertz_1.feature x/logic/keeper/features/retract_1.feature
Length of output: 9702
x/logic/keeper/features/assertz_1.feature (3)
35-58
: LGTM! Well-documented error handling scenario.
The scenario effectively demonstrates and documents the distinction between static and dynamic predicates, with appropriate error handling.
1-127
: Excellent feature file implementation!
The feature file provides comprehensive testing of the assertz/1
predicate with:
- Clear documentation and explanations
- Good coverage of different use cases
- Practical examples
- Appropriate error handling
The scenarios effectively demonstrate both basic functionality and real-world applications.
22-23
: Verify if the static height value is intentional.
The height value appears to be hardcoded to 42 in the test case. This might not accurately reflect real-world behavior where block heights typically increment.
✅ Verification successful
Static height value of 42 is a consistent test pattern
The hardcoded height value of 42 appears to be an intentional testing pattern used consistently across multiple feature files in the x/logic/keeper/features/
directory. This includes tests for various functionalities like assertz
, asserta
, retract
, consult
, and others. Since this is a widespread pattern in the test suite, it's clearly a deliberate choice for test scenarios rather than an oversight.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other test files to see if this is a common pattern
rg -g "*.feature" "height: 42"
Length of output: 3044
x/logic/keeper/features/asserta_1.feature (3)
4-33
: LGTM! Well-structured test case with clear documentation.
The scenario effectively demonstrates the basic functionality of asserta/1
with proper documentation and clear expected results.
59-93
: LGTM! Excellent demonstration of asserta/1 ordering behavior.
The scenario effectively demonstrates and verifies the key differentiator between asserta/1
and assertz/1
with clear documentation and proper test assertions.
95-130
: Consider addressing potential race conditions and error handling.
While the counter example effectively demonstrates the usage, there are two concerns to consider:
- The current implementation could face race conditions in a concurrent environment as the
retract/1
andasserta/1
operations aren't atomic. - The implementation doesn't handle the case where the counter fact doesn't exist.
Consider:
- Adding a note about concurrent access limitations
- Adding error handling for missing counter:
increment_counter :- retract(counter(X)), Y is X + 1, asserta(counter(Y)).
decrement_counter :- retract(counter(X)), Y is X - 1, asserta(counter(Y)).
+
+% Add error handling
+safe_increment_counter :-
+ (counter(X) ->
+ retract(counter(X)),
+ Y is X + 1,
+ asserta(counter(Y))
+ ;
+ asserta(counter(0))
+ ).
@coderabbitai please approve PR. thx |
@ccamel: I've approved the PR. Thank you. ✅ Actions performedComments resolved. |
Expose the ISO predicates related to “database” management, specifically those used for handling dynamic predicates.
Summary by CodeRabbit
asserta/1
,assertz/1
, andretract/1
predicates in Prolog, with multiple scenarios demonstrating their functionality.