Skip to content

Commit

Permalink
bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
git-afsantos committed Sep 4, 2023
1 parent 9a35291 commit ca35ada
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## v1.1.2 - 2023-09-04
### Fixed
- Sanity error when creating some types of predicates that was too strict.

## v1.1.1 - 2023-09-04
### Fixed
- Exception when parsing specifications.
Expand Down
31 changes: 20 additions & 11 deletions src/hpl/ast/predicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,9 @@ class HplPredicateExpression(HplPredicate):
def _check_expression(self, _attribute, expr: HplExpression):
if not expr.can_be_bool:
raise TypeError(f'not a boolean expression: {{{expr}}}')
ref_table = {}
for obj in expr.iterate():
assert isinstance(obj, HplExpression)
if obj.is_accessor or (obj.is_value and obj.is_variable):
key = str(obj)
refs = ref_table.get(key)
if refs is None:
refs = []
ref_table[key] = refs
refs.append(obj)
ref_table = _get_reference_table(expr)
self._all_refs_same_type(ref_table)
self._some_field_refs(ref_table)
# self._some_field_refs(ref_table)

def _all_refs_same_type(self, table: Dict[str, List[HplExpression]]):
# All references to the same field/variable have the same type.
Expand All @@ -117,6 +108,10 @@ def _all_refs_same_type(self, table: Dict[str, List[HplExpression]]):
for ref in reversed(ref_group):
final_type = ref.data_type.cast(final_type)

def check_some_self_references(self):
ref_table = _get_reference_table(self.expression)
self._some_field_refs(ref_table)

def _some_field_refs(self, table: Dict[str, List[HplExpression]]):
# There is at least one reference to a field (own).
# [NYI] Stricter: one reference per atomic condition.
Expand Down Expand Up @@ -283,6 +278,20 @@ def __str__(self) -> str:
###############################################################################


def _get_reference_table(expr: HplExpression) -> Dict[str, List[HplExpression]]:
ref_table = {}
for obj in expr.iterate():
assert isinstance(obj, HplExpression)
if obj.is_accessor or (obj.is_value and obj.is_variable):
key = str(obj)
refs = ref_table.get(key)
if refs is None:
refs = []
ref_table[key] = refs
refs.append(obj)
return ref_table


def predicate_from_expression(expr: HplExpression) -> HplPredicate:
if not expr.can_be_bool:
raise invalid_type('boolean', expr)
Expand Down
10 changes: 4 additions & 6 deletions tests/test_invalid_predicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from pytest import raises

from hpl.ast.predicates import HplPredicateExpression
from hpl.errors import HplSanityError, HplSyntaxError
from hpl.parser import condition_parser

Expand Down Expand Up @@ -96,14 +97,11 @@ def test_all_eq_refs_have_same_type():
parser.parse('exists x in xs: (a[@x] implies @x)')


def test_no_unknown_refs():
with raises(HplSanityError):
parser.parse('@a < 3')


def test_at_least_one_self_ref():
with raises(HplSanityError):
parser.parse('---42 = -42')
p = parser.parse('---42 = -42')
assert isinstance(p, HplPredicateExpression)
p.check_some_self_references()


def test_unknown_function():
Expand Down

0 comments on commit ca35ada

Please sign in to comment.