Skip to content

Commit

Permalink
Merge pull request #56 from ngeiswei/improv-cogscm-syntax
Browse files Browse the repository at this point in the history
Improve cogscm syntax
  • Loading branch information
ngeiswei authored Feb 8, 2022
2 parents 9fd5f06 + f37dc3f commit e5ed4bf
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 27 deletions.
50 changes: 48 additions & 2 deletions rocca/agents/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import random
import math
from typing import Any

from functools import cmp_to_key
from orderedmultidict import omdict

# SciPy
Expand Down Expand Up @@ -395,6 +395,18 @@ def has_variables_leq(cogscm: Atom, vc: int) -> bool:
return vardecl_size(get_vardecl(cogscm)) <= vc


def is_ordered(atom: Atom) -> bool:
"""Return true iff the atom inherits from the OrderedLink type."""

return is_a(atom.type, types.OrderedLink)


def is_unordered(atom: Atom) -> bool:
"""Return true iff the atom inherits from the UnorderedLink type."""

return is_a(atom.type, types.UnorderedLink)


def is_virtual(clause: Atom) -> bool:
"""Return true iff the clause is virtual.
Expand Down Expand Up @@ -1003,10 +1015,42 @@ def get_uniq_atoms(atom: Atom) -> set[Atom]:
return result


def syntax_lt(a1: Atom, a2: Atom) -> bool:
"""Custom less-than function for unordered links.
It is used by to_human_readable_str to place the do(Action) to the
right, so that for instance
do(Eat) ∧ AgentPosition(RightSquare) ↝ Reward(1)
becomes
AgentPosition(RightSquare) ∧ do(Eat) ↝ Reward(1)
which makes it easier to read and search.
"""

return (not is_execution(a1) and is_execution(a2)) or a1 < a2


def syntax_cmp(a1: Atom, a2: Atom) -> int:
"""Compare function based on syntax_lt for to_human_readable_str."""

if a1 == a2:
return 0
elif syntax_lt(a1, a2):
return -1
else:
return 1


def syntax_precede(a1: Atom, a2: Atom) -> bool:

"""Return true iff a1 syntactically precedes a2.
This function is used by to_human_readable_str
This function is used by to_human_readable_str to minimize the
number of parenthesis.
Precedence order is as follows
Expand Down Expand Up @@ -1182,6 +1226,8 @@ def to_human_readable_str(atom: Atom, parenthesis: bool = False) -> str:
is_infix = False
else:
out = atom.out
if is_unordered(atom):
out = sorted(out, key=cmp_to_key(syntax_cmp))
op_str = type_to_human_readable_str(atom.type)

# Recursively convert outgoings to human readable strings, adding
Expand Down
34 changes: 9 additions & 25 deletions tests/agents/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,9 @@ def test_to_human_readable_str():
)

cogscm_hrs_1 = to_human_readable_str(cogscm_1)
expected_1 = "outside(self, house) ∧ do(go_to_key) ↝ hold(self, key)"

# Two expected results due to AndLink commutativity
expected_1a = "outside(self, house) ∧ do(go_to_key) ↝ hold(self, key)"
expected_1b = "do(go_to_key) ∧ outside(self, house) ↝ hold(self, key)"

assert cogscm_hrs_1 == expected_1a or cogscm_hrs_1 == expected_1b
assert cogscm_hrs_1 == expected_1

# 2. AgentPosition(RightSquare) ∧ do(Eat) ↝ Reward(1)
# Check that whitespace is removed in names
Expand All @@ -220,12 +217,9 @@ def test_to_human_readable_str():
)

cogscm_hrs_2 = to_human_readable_str(cogscm_2)
expected_2 = "AgentPosition(RightSquare) ∧ do(Eat) ↝ Reward(1)"

# Two expected results due to AndLink commutativity
expected_2a = "AgentPosition(RightSquare) ∧ do(Eat) ↝ Reward(1)"
expected_2b = "do(Eat) ∧ AgentPosition(RightSquare) ↝ Reward(1)"

assert cogscm_hrs_2 == expected_2a or cogscm_hrs_2 == expected_2b
assert cogscm_hrs_2 == expected_2

# 3. -0.01 > $angle ∧ PoleAngle($angle) ∧ do(GoLeft) ↝ Reward(1)
# Test with variable and GreaterThanLink
Expand All @@ -242,19 +236,9 @@ def test_to_human_readable_str():

cogscm_hrs_3 = to_human_readable_str(cogscm_3)

# Six expected results due to AndLink commutativity
# Two expected results due to AndLink commutativity (in spite of
# actions being moved to the right)
expected_3a = "-0.01 > $angle ∧ PoleAngle($angle) ∧ do(GoLeft) ↝ Reward(1)"
expected_3b = "-0.01 > $angle ∧ do(GoLeft) ∧ PoleAngle($angle) ↝ Reward(1)"
expected_3c = "do(GoLeft) ∧ -0.01 > $angle ∧ PoleAngle($angle) ↝ Reward(1)"
expected_3d = "PoleAngle($angle) ∧ -0.01 > $angle ∧ do(GoLeft) ↝ Reward(1)"
expected_3e = "PoleAngle($angle) ∧ -0.01 > $angle ∧ do(GoLeft) ↝ Reward(1)"
expected_3f = "PoleAngle($angle) ∧ do(GoLeft) ∧ -0.01 > $angle ↝ Reward(1)"

assert (
cogscm_hrs_3 == expected_3a
or cogscm_hrs_3 == expected_3b
or cogscm_hrs_3 == expected_3c
or cogscm_hrs_3 == expected_3d
or cogscm_hrs_3 == expected_3e
or cogscm_hrs_3 == expected_3f
)
expected_3b = "PoleAngle($angle) ∧ -0.01 > $angle ∧ do(GoLeft) ↝ Reward(1)"

assert cogscm_hrs_3 == expected_3a or cogscm_hrs_3 == expected_3b

0 comments on commit e5ed4bf

Please sign in to comment.