Added is_lesser and is_greatest in SheerkaComparison
This commit is contained in:
+9
-7
@@ -84,10 +84,10 @@ def concept plus from a plus b as a + b
|
|||||||
def concept minus from a minus b as a - b
|
def concept minus from a minus b as a - b
|
||||||
def concept multiplied from a multiplied by b as a * b
|
def concept multiplied from a multiplied by b as a * b
|
||||||
def concept divided from a divided by b as a * b
|
def concept divided from a divided by b as a * b
|
||||||
set_is_greater_than(BuiltinConcepts.PRECEDENCE, multiplied, plus)
|
set_is_greater_than(__PRECEDENCE, multiplied, plus)
|
||||||
set_is_greater_than(BuiltinConcepts.PRECEDENCE, divided, plus)
|
set_is_greater_than(__PRECEDENCE, divided, plus)
|
||||||
set_is_greater_than(BuiltinConcepts.PRECEDENCE, multiplied, minus)
|
set_is_greater_than(__PRECEDENCE, multiplied, minus)
|
||||||
set_is_greater_than(BuiltinConcepts.PRECEDENCE, divided, minus)
|
set_is_greater_than(__PRECEDENCE, divided, minus)
|
||||||
def concept explain as get_results() | filter("id == 0") | recurse(2)
|
def concept explain as get_results() | filter("id == 0") | recurse(2)
|
||||||
def concept explain last as get_last_results() | filter("id == 0") | recurse(2)
|
def concept explain last as get_last_results() | filter("id == 0") | recurse(2)
|
||||||
def concept explain x as get_results() | filter(f"id == {x}") | recurse(3) where x
|
def concept explain x as get_results() | filter(f"id == {x}") | recurse(3) where x
|
||||||
@@ -95,9 +95,11 @@ def concept explain x '--recurse' y as get_results() | filter(f"id == {x}") | re
|
|||||||
set_isa(c:explain:, __COMMAND)
|
set_isa(c:explain:, __COMMAND)
|
||||||
set_isa(c:explain last:, __COMMAND)
|
set_isa(c:explain last:, __COMMAND)
|
||||||
set_isa(c:explain x:, __COMMAND)
|
set_isa(c:explain x:, __COMMAND)
|
||||||
def concept precedence a > precedence b as set_is_greater_than(BuiltinConcepts.PRECEDENCE, a, b)
|
def concept precedence a > precedence b as set_is_greater_than(__PRECEDENCE, a, b)
|
||||||
set_isa(c:precedence a > precedence b:, __COMMAND)
|
set_isa(c:precedence a > precedence b:, __COMMAND)
|
||||||
def concept x is a command as set_isa(x, __COMMAND)
|
def concept x is a command as set_isa(x, __COMMAND)
|
||||||
set_isa(c:x is a command:, __COMMAND)
|
set_isa(c:x is a command:, __COMMAND)
|
||||||
def concept q from q ? as question(q) pre in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
|
def concept q from q ? as question(q) pre is_question()
|
||||||
def concept x is a 'concept' as isinstance(x, Concept) pre in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
|
set_is_lesser(__PRECEDENCE, q)
|
||||||
|
def concept x is a 'concept' as isinstance(x, Concept) pre is_question()
|
||||||
|
def concept x is a y as isa(x,y) pre is_question()
|
||||||
@@ -72,7 +72,7 @@ class BuiltinConcepts(Enum):
|
|||||||
IS_EMPTY = "is empty" # when a set is empty
|
IS_EMPTY = "is empty" # when a set is empty
|
||||||
NO_RESULT = "no result" # no return value returned
|
NO_RESULT = "no result" # no return value returned
|
||||||
INVALID_RETURN_VALUE = "invalid return value" # the return value of an evaluator is not correct
|
INVALID_RETURN_VALUE = "invalid return value" # the return value of an evaluator is not correct
|
||||||
CONCEPT_ALREADY_DEFINED = "concept already defined" # when you try to add the same concept twice
|
ALREADY_DEFINED = "already defined" # when you try to add the same object twice (a concept or whatever)
|
||||||
NOP = "no operation" # no operation concept. Does nothing
|
NOP = "no operation" # no operation concept. Does nothing
|
||||||
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
|
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
|
||||||
ENUMERATION = "enum" # represents a list or a set
|
ENUMERATION = "enum" # represents a list or a set
|
||||||
@@ -91,6 +91,8 @@ class BuiltinConcepts(Enum):
|
|||||||
FORMAT_INSTRUCTIONS = "format instructions" # to express how to print the concept
|
FORMAT_INSTRUCTIONS = "format instructions" # to express how to print the concept
|
||||||
NOT_IMPLEMENTED = "not implemented" # instead of raise an error
|
NOT_IMPLEMENTED = "not implemented" # instead of raise an error
|
||||||
PYTHON_SECURITY_ERROR = "security error" # when trying to execute statement when only expression is allowed
|
PYTHON_SECURITY_ERROR = "security error" # when trying to execute statement when only expression is allowed
|
||||||
|
INVALID_LESSER_OPERATION = "Invalid lesser operation"
|
||||||
|
INVALID_GREATEST_OPERATION = "Invalid greatest operation"
|
||||||
|
|
||||||
NODE = "node"
|
NODE = "node"
|
||||||
GENERIC_NODE = "generic node"
|
GENERIC_NODE = "generic node"
|
||||||
@@ -152,6 +154,9 @@ BuiltinUnique = [
|
|||||||
|
|
||||||
BuiltinConcepts.ISA,
|
BuiltinConcepts.ISA,
|
||||||
BuiltinConcepts.COMMAND,
|
BuiltinConcepts.COMMAND,
|
||||||
|
|
||||||
|
BuiltinConcepts.INVALID_LESSER_OPERATION,
|
||||||
|
BuiltinConcepts.INVALID_GREATEST_OPERATION,
|
||||||
]
|
]
|
||||||
|
|
||||||
BuiltinErrors = [str(e) for e in {
|
BuiltinErrors = [str(e) for e in {
|
||||||
@@ -164,14 +169,16 @@ BuiltinErrors = [str(e) for e in {
|
|||||||
BuiltinConcepts.TOO_MANY_ERRORS,
|
BuiltinConcepts.TOO_MANY_ERRORS,
|
||||||
BuiltinConcepts.MULTIPLE_ERRORS,
|
BuiltinConcepts.MULTIPLE_ERRORS,
|
||||||
BuiltinConcepts.INVALID_RETURN_VALUE,
|
BuiltinConcepts.INVALID_RETURN_VALUE,
|
||||||
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
|
BuiltinConcepts.ALREADY_DEFINED,
|
||||||
BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
||||||
BuiltinConcepts.NOT_A_SET,
|
BuiltinConcepts.NOT_A_SET,
|
||||||
BuiltinConcepts.CONDITION_FAILED,
|
BuiltinConcepts.CONDITION_FAILED,
|
||||||
BuiltinConcepts.CHICKEN_AND_EGG,
|
BuiltinConcepts.CHICKEN_AND_EGG,
|
||||||
BuiltinConcepts.NOT_INITIALIZED,
|
BuiltinConcepts.NOT_INITIALIZED,
|
||||||
BuiltinConcepts.NOT_FOUND
|
BuiltinConcepts.NOT_FOUND,
|
||||||
|
BuiltinConcepts.INVALID_LESSER_OPERATION,
|
||||||
|
BuiltinConcepts.INVALID_GREATEST_OPERATION,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from dataclasses import dataclass
|
|||||||
from cache.Cache import Cache
|
from cache.Cache import Cache
|
||||||
from cache.ListCache import ListCache
|
from cache.ListCache import ListCache
|
||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import ensure_concept
|
from core.concept import ensure_concept, Concept
|
||||||
from core.sheerka.services.sheerka_service import ServiceObj, BaseService
|
from core.sheerka.services.sheerka_service import ServiceObj, BaseService
|
||||||
|
|
||||||
|
|
||||||
@@ -27,15 +27,30 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
COMPARISON_ENTRY = "ComparisonManager:Comparison"
|
COMPARISON_ENTRY = "ComparisonManager:Comparison"
|
||||||
RESOLVED_COMPARISON_ENTRY = "ComparisonManager:Resolved_Comparison"
|
RESOLVED_COMPARISON_ENTRY = "ComparisonManager:Resolved_Comparison"
|
||||||
|
|
||||||
|
# to use an initialisation value for attributes that will make use of computed weights
|
||||||
|
# the lesser and the greatest weight will be given relatively to this value
|
||||||
|
DEFAULT_COMPARISON_VALUE = 1
|
||||||
|
|
||||||
def __init__(self, sheerka):
|
def __init__(self, sheerka):
|
||||||
super().__init__(sheerka)
|
super().__init__(sheerka)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _compute_key(prop_name, comparison_context):
|
def _compute_key(prop_name, comparison_context):
|
||||||
return f"{prop_name}|{comparison_context}"
|
"""
|
||||||
|
Key to use to store the comparisons
|
||||||
|
:param prop_name:
|
||||||
|
:param comparison_context:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if isinstance(prop_name, Concept):
|
||||||
|
prefix = prop_name.key if prop_name.metadata.is_builtin else prop_name.id
|
||||||
|
else:
|
||||||
|
prefix = prop_name
|
||||||
|
|
||||||
|
return f"{prefix}|{comparison_context}"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _compute_weights(comparison_objs):
|
def _get_weights(comparison_objs):
|
||||||
"""
|
"""
|
||||||
For every element in greater_than_s, give it a weight
|
For every element in greater_than_s, give it a weight
|
||||||
if weight(a) > weight(b) it means that a > b
|
if weight(a) > weight(b) it means that a > b
|
||||||
@@ -45,8 +60,8 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
|
|
||||||
values = {}
|
values = {}
|
||||||
for comparison_obj in comparison_objs:
|
for comparison_obj in comparison_objs:
|
||||||
values[comparison_obj.a] = 1
|
values[comparison_obj.a] = SheerkaComparisonManager.DEFAULT_COMPARISON_VALUE
|
||||||
values[comparison_obj.b] = 1
|
values[comparison_obj.b] = SheerkaComparisonManager.DEFAULT_COMPARISON_VALUE
|
||||||
|
|
||||||
for _ in range(len(comparison_objs)):
|
for _ in range(len(comparison_objs)):
|
||||||
for comparison_obj in comparison_objs:
|
for comparison_obj in comparison_objs:
|
||||||
@@ -57,6 +72,54 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
def _compute_weights(self, comparison_objs, lesser_objs_ids=None, greatest_objs_ids=None):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param comparison_objs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
def is_not_in_objs(obj, objs_ids):
|
||||||
|
return obj.op in ("<", ">") and obj.a not in objs_ids and obj.b not in objs_ids
|
||||||
|
|
||||||
|
def is_in_objs(obj, objs_ids):
|
||||||
|
return obj.op in ("<", ">") and (obj.a in objs_ids or obj.b in objs_ids)
|
||||||
|
|
||||||
|
lesser_objs_ids = lesser_objs_ids or {co.a for co in comparison_objs if co.op == "<<"}
|
||||||
|
greatest_objs_ids = greatest_objs_ids or {co.a for co in comparison_objs if co.op == ">>"}
|
||||||
|
|
||||||
|
default_weight = SheerkaComparisonManager.DEFAULT_COMPARISON_VALUE
|
||||||
|
|
||||||
|
# get the weights for all the lesser
|
||||||
|
lesser_objs = [co for co in comparison_objs if is_in_objs(co, lesser_objs_ids)]
|
||||||
|
lesser_objs_weights = self._get_weights(lesser_objs)
|
||||||
|
|
||||||
|
# rearrange the weight to have the highest equals to DEFAULT_COMPARISON_VALUE - 1
|
||||||
|
highest_weight = len(lesser_objs_weights)
|
||||||
|
for co_id in lesser_objs_weights:
|
||||||
|
lesser_objs_weights[co_id] = lesser_objs_weights[co_id] - highest_weight + default_weight - 1
|
||||||
|
for concept_id in lesser_objs_ids:
|
||||||
|
if concept_id not in lesser_objs_weights:
|
||||||
|
lesser_objs_weights[concept_id] = default_weight - 1
|
||||||
|
|
||||||
|
# get the weights for concepts that are not lesser or greatest
|
||||||
|
in_between_objs = [o for o in comparison_objs if is_not_in_objs(o, lesser_objs_ids | greatest_objs_ids)]
|
||||||
|
in_between_weights = self._get_weights(in_between_objs)
|
||||||
|
|
||||||
|
# get the weights for all the greatest
|
||||||
|
greatest_objs = [co for co in comparison_objs if is_in_objs(co, greatest_objs_ids)]
|
||||||
|
greatest_objs_weights = self._get_weights(greatest_objs)
|
||||||
|
|
||||||
|
# rearrange the weight to have the lowest equals to DEFAULT_COMPARISON_VALUE + 1
|
||||||
|
highest_weight = max(default_weight, len(in_between_weights))
|
||||||
|
for co_id in greatest_objs_weights:
|
||||||
|
greatest_objs_weights[co_id] = greatest_objs_weights[co_id] + highest_weight
|
||||||
|
for concept_id in greatest_objs_ids:
|
||||||
|
if concept_id not in greatest_objs_weights:
|
||||||
|
greatest_objs_weights[concept_id] = highest_weight + 1
|
||||||
|
|
||||||
|
return {**lesser_objs_weights, **in_between_weights, **greatest_objs_weights}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_partition(weighted_concepts):
|
def _get_partition(weighted_concepts):
|
||||||
|
|
||||||
@@ -65,21 +128,52 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
res.setdefault(v, []).append(k)
|
res.setdefault(v, []).append(k)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _inner_add_comparison(self, comparison_obj):
|
def _add_comparison(self, comparison_obj):
|
||||||
key = self._compute_key(comparison_obj.property, comparison_obj.context)
|
key = self._compute_key(comparison_obj.property, comparison_obj.context)
|
||||||
previous = self.sheerka.cache_manager.get(self.COMPARISON_ENTRY, key)
|
previous = self.sheerka.cache_manager.get(self.COMPARISON_ENTRY, key)
|
||||||
|
|
||||||
new = previous.copy() if previous else []
|
new = previous.copy() if previous else []
|
||||||
|
|
||||||
|
for co in new:
|
||||||
|
if co.property == comparison_obj.property and \
|
||||||
|
co.a == comparison_obj.a and \
|
||||||
|
co.b == comparison_obj.b and \
|
||||||
|
co.op == comparison_obj.op and \
|
||||||
|
co.context == comparison_obj.context:
|
||||||
|
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.ALREADY_DEFINED))
|
||||||
|
|
||||||
new.append(comparison_obj)
|
new.append(comparison_obj)
|
||||||
|
|
||||||
|
lesser_objs_ids = {co.a for co in new if co.op == "<<"}
|
||||||
|
greatest_objs_ids = {co.a for co in new if co.op == ">>"}
|
||||||
|
|
||||||
|
# check if it is a valid operation regarding other lesser and greatest concepts
|
||||||
|
if comparison_obj.op in ("<", ">"):
|
||||||
|
a_is_lesser = comparison_obj.a in lesser_objs_ids
|
||||||
|
b_is_lesser = comparison_obj.b in lesser_objs_ids
|
||||||
|
if a_is_lesser != b_is_lesser: # XOR operation
|
||||||
|
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.INVALID_LESSER_OPERATION))
|
||||||
|
|
||||||
|
a_is_greatest = comparison_obj.a in greatest_objs_ids
|
||||||
|
b_is_greatest = comparison_obj.b in greatest_objs_ids
|
||||||
|
if a_is_greatest != b_is_greatest: # XOR operation
|
||||||
|
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.INVALID_GREATEST_OPERATION))
|
||||||
|
|
||||||
|
if comparison_obj.op == "<<" and comparison_obj.a in greatest_objs_ids:
|
||||||
|
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.INVALID_GREATEST_OPERATION))
|
||||||
|
|
||||||
|
if comparison_obj.op == ">>" and comparison_obj.a in lesser_objs_ids:
|
||||||
|
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.INVALID_LESSER_OPERATION))
|
||||||
|
|
||||||
cycles = self.detect_cycles(new)
|
cycles = self.detect_cycles(new)
|
||||||
if cycles:
|
if cycles:
|
||||||
concepts_in_cycle = [self.sheerka.get_by_id(c) for c in cycles]
|
concepts_in_cycle = [self.sheerka.get_by_id(c) for c in cycles]
|
||||||
chicken_an_egg = self.sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body=concepts_in_cycle)
|
chicken_an_egg = self.sheerka.new(BuiltinConcepts.CHICKEN_AND_EGG, body=concepts_in_cycle)
|
||||||
return self.sheerka.ret(self.NAME, False, chicken_an_egg)
|
return self.sheerka.ret(self.NAME, False, chicken_an_egg)
|
||||||
|
|
||||||
self.sheerka.cache_manager.put(self.RESOLVED_COMPARISON_ENTRY, key, self._compute_weights(new))
|
|
||||||
self.sheerka.cache_manager.put(self.COMPARISON_ENTRY, key, comparison_obj)
|
self.sheerka.cache_manager.put(self.COMPARISON_ENTRY, key, comparison_obj)
|
||||||
|
self.sheerka.cache_manager.put(self.RESOLVED_COMPARISON_ENTRY, key, self._compute_weights(new,
|
||||||
|
lesser_objs_ids,
|
||||||
|
greatest_objs_ids))
|
||||||
|
|
||||||
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||||
|
|
||||||
@@ -92,6 +186,8 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
|
|
||||||
self.sheerka.bind_service_method(self.set_is_greater_than, True)
|
self.sheerka.bind_service_method(self.set_is_greater_than, True)
|
||||||
self.sheerka.bind_service_method(self.set_is_less_than, True)
|
self.sheerka.bind_service_method(self.set_is_less_than, True)
|
||||||
|
self.sheerka.bind_service_method(self.set_is_lesser, True)
|
||||||
|
self.sheerka.bind_service_method(self.set_is_greatest, True)
|
||||||
self.sheerka.bind_service_method(self.get_partition, False)
|
self.sheerka.bind_service_method(self.get_partition, False)
|
||||||
self.sheerka.bind_service_method(self.get_concepts_weights, False)
|
self.sheerka.bind_service_method(self.get_concepts_weights, False)
|
||||||
|
|
||||||
@@ -110,7 +206,7 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
|
|
||||||
event_digest = context.event.get_digest()
|
event_digest = context.event.get_digest()
|
||||||
comparison_obj = ComparisonObj(event_digest, prop_name, concept_a.id, concept_b.id, ">", comparison_context)
|
comparison_obj = ComparisonObj(event_digest, prop_name, concept_a.id, concept_b.id, ">", comparison_context)
|
||||||
return self._inner_add_comparison(comparison_obj)
|
return self._add_comparison(comparison_obj)
|
||||||
|
|
||||||
def set_is_less_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
def set_is_less_than(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||||
"""
|
"""
|
||||||
@@ -127,7 +223,66 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
|
|
||||||
event_digest = context.event.get_digest()
|
event_digest = context.event.get_digest()
|
||||||
comparison_obj = ComparisonObj(event_digest, prop_name, concept_a.id, concept_b.id, "<", comparison_context)
|
comparison_obj = ComparisonObj(event_digest, prop_name, concept_a.id, concept_b.id, "<", comparison_context)
|
||||||
return self._inner_add_comparison(comparison_obj)
|
return self._add_comparison(comparison_obj)
|
||||||
|
|
||||||
|
def set_is_lesser(self, context, prop_name, concept, comparison_context="#"):
|
||||||
|
"""
|
||||||
|
Records that the concept is less than any other concept if no direct comparison is given
|
||||||
|
|
||||||
|
* A lesser concept has a weight smaller than any other concept that is not a lesser
|
||||||
|
* When two concepts are lesser, you can compare (using set_is_less_than or set_is_greater_than)
|
||||||
|
* If a concept is lesser, you cannot compare it with a non lesser concept
|
||||||
|
* All lesser concepts that have no comparison directive are greater than the others (and share the same weight)
|
||||||
|
:param context:
|
||||||
|
:param prop_name:
|
||||||
|
:param concept:
|
||||||
|
:param comparison_context:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
context.log(f"Setting concept {concept} is lesser", who=self.NAME)
|
||||||
|
ensure_concept(concept)
|
||||||
|
|
||||||
|
event_digest = context.event.get_digest()
|
||||||
|
comparison_obj = ComparisonObj(event_digest, prop_name, concept.id, None, "<<", comparison_context)
|
||||||
|
return self._add_comparison(comparison_obj)
|
||||||
|
|
||||||
|
def set_is_greatest(self, context, prop_name, concept, comparison_context="#"):
|
||||||
|
"""
|
||||||
|
Records that the concept is greater than any other concept if no direct comparison is given
|
||||||
|
|
||||||
|
* A greatest concept has a weight bigger than any other concept that is not a greatest
|
||||||
|
* When two concepts are greatest, you can compare them (using set_is_less_than or set_is_greater_than)
|
||||||
|
* If a concept is greatest, you cannot compare it with a non greatest concept
|
||||||
|
* All greatest concepts that have no comparison directive are less than the others (and share the same weight)
|
||||||
|
:param context:
|
||||||
|
:param prop_name:
|
||||||
|
:param concept:
|
||||||
|
:param comparison_context:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
context.log(f"Setting concept {concept} is greatest", who=self.NAME)
|
||||||
|
ensure_concept(concept)
|
||||||
|
|
||||||
|
event_digest = context.event.get_digest()
|
||||||
|
comparison_obj = ComparisonObj(event_digest, prop_name, concept.id, None, ">>", comparison_context)
|
||||||
|
return self._add_comparison(comparison_obj)
|
||||||
|
|
||||||
|
def set_are_equivalent(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||||
|
"""
|
||||||
|
Records that two concepts have the same weight
|
||||||
|
|
||||||
|
* You cannot set the weight
|
||||||
|
:param context:
|
||||||
|
:param prop_name:
|
||||||
|
:param concept_a:
|
||||||
|
:param concept_b:
|
||||||
|
:param comparison_context:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_are_equiv(self, context, prop_name, concept_a, concept_b, comparison_context="#"):
|
||||||
|
pass
|
||||||
|
|
||||||
def get_partition(self, prop_name, comparison_context="#"):
|
def get_partition(self, prop_name, comparison_context="#"):
|
||||||
"""
|
"""
|
||||||
@@ -141,21 +296,21 @@ class SheerkaComparisonManager(BaseService):
|
|||||||
return self._get_partition(weighted_concept)
|
return self._get_partition(weighted_concept)
|
||||||
|
|
||||||
def get_concepts_weights(self, prop_name, comparison_context="#"):
|
def get_concepts_weights(self, prop_name, comparison_context="#"):
|
||||||
weighted_concept = self.sheerka.cache_manager.get(
|
weighted_concepts = self.sheerka.cache_manager.get(
|
||||||
self.RESOLVED_COMPARISON_ENTRY,
|
self.RESOLVED_COMPARISON_ENTRY,
|
||||||
self._compute_key(prop_name, comparison_context))
|
self._compute_key(prop_name, comparison_context))
|
||||||
|
|
||||||
if weighted_concept is None:
|
if weighted_concepts is None:
|
||||||
key = self._compute_key(prop_name, comparison_context)
|
key = self._compute_key(prop_name, comparison_context)
|
||||||
entries = self.sheerka.cache_manager.get(self.COMPARISON_ENTRY, key)
|
entries = self.sheerka.cache_manager.get(self.COMPARISON_ENTRY, key)
|
||||||
|
|
||||||
if entries is None:
|
if entries is None:
|
||||||
return {}
|
return {}
|
||||||
else:
|
else:
|
||||||
weighted_concept = self._compute_weights(entries)
|
weighted_concepts = self._compute_weights(entries)
|
||||||
self.sheerka.cache_manager.put(self.RESOLVED_COMPARISON_ENTRY, key, weighted_concept)
|
self.sheerka.cache_manager.put(self.RESOLVED_COMPARISON_ENTRY, key, weighted_concepts)
|
||||||
|
|
||||||
return weighted_concept
|
return weighted_concepts
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def detect_cycles(comparison_objs):
|
def detect_cycles(comparison_objs):
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class SheerkaCreateNewConcept(BaseService):
|
|||||||
return sheerka.ret(
|
return sheerka.ret(
|
||||||
self.NAME,
|
self.NAME,
|
||||||
False,
|
False,
|
||||||
sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
|
sheerka.new(BuiltinConcepts.ALREADY_DEFINED, body=concept),
|
||||||
error.args[0])
|
error.args[0])
|
||||||
|
|
||||||
# set id before saving in db
|
# set id before saving in db
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class SheerkaModifyConcept(BaseService):
|
|||||||
return self.sheerka.ret(
|
return self.sheerka.ret(
|
||||||
self.NAME, False,
|
self.NAME, False,
|
||||||
self.sheerka.new(
|
self.sheerka.new(
|
||||||
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
|
BuiltinConcepts.ALREADY_DEFINED,
|
||||||
body=concept))
|
body=concept))
|
||||||
|
|
||||||
old_references = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_REFERENCES_ENTRY, concept.id)
|
old_references = self.sheerka.cache_manager.get(self.sheerka.CONCEPTS_REFERENCES_ENTRY, concept.id)
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ class Expando:
|
|||||||
for k, v in bag.items():
|
for k, v in bag.items():
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{dir(self)}"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PythonEvalError:
|
class PythonEvalError:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from typing import List
|
|||||||
from core import builtin_helpers
|
from core import builtin_helpers
|
||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import Concept, DEFINITION_TYPE_BNF
|
from core.concept import Concept, DEFINITION_TYPE_BNF
|
||||||
|
from core.sheerka.services.SheerkaComparisonManager import SheerkaComparisonManager
|
||||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||||
from parsers.BaseNodeParser import UnrecognizedTokensNode, ConceptNode, SourceCodeNode, SyaAssociativity, \
|
from parsers.BaseNodeParser import UnrecognizedTokensNode, ConceptNode, SourceCodeNode, SyaAssociativity, \
|
||||||
@@ -77,7 +78,7 @@ class SyaConceptDef:
|
|||||||
It gives the precedence and the associativity for the concept
|
It gives the precedence and the associativity for the concept
|
||||||
"""
|
"""
|
||||||
concept: Concept
|
concept: Concept
|
||||||
precedence: int = 0
|
precedence: int = SheerkaComparisonManager.DEFAULT_COMPARISON_VALUE
|
||||||
associativity: SyaAssociativity = SyaAssociativity.Right
|
associativity: SyaAssociativity = SyaAssociativity.Right
|
||||||
|
|
||||||
|
|
||||||
@@ -541,11 +542,6 @@ class InFixToPostFix:
|
|||||||
if stack.associativity == SyaAssociativity.No and current.associativity == SyaAssociativity.No:
|
if stack.associativity == SyaAssociativity.No and current.associativity == SyaAssociativity.No:
|
||||||
self._add_error(NoneAssociativeSequenceErrorNode(current.concept, stack_head.start, concept_node.start))
|
self._add_error(NoneAssociativeSequenceErrorNode(current.concept, stack_head.start, concept_node.start))
|
||||||
|
|
||||||
if not current.precedence:
|
|
||||||
# precedence is not set (None or zero)
|
|
||||||
# Do not apply any rule
|
|
||||||
return False
|
|
||||||
|
|
||||||
if current.associativity == SyaAssociativity.Left and current.precedence <= stack.precedence:
|
if current.associativity == SyaAssociativity.Left and current.precedence <= stack.precedence:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -947,6 +943,7 @@ class SyaNodeParser(BaseNodeParser):
|
|||||||
def _get_sya_concept_def(parser, concept):
|
def _get_sya_concept_def(parser, concept):
|
||||||
sya_concept_def = SyaConceptDef(concept)
|
sya_concept_def = SyaConceptDef(concept)
|
||||||
if concept.id in parser.sya_definitions:
|
if concept.id in parser.sya_definitions:
|
||||||
|
# Manage when precedence and associativity are given in the unit tests
|
||||||
sya_def = parser.sya_definitions.get(concept.id)
|
sya_def = parser.sya_definitions.get(concept.id)
|
||||||
if sya_def[0] is not None:
|
if sya_def[0] is not None:
|
||||||
sya_concept_def.precedence = sya_def[0]
|
sya_concept_def.precedence = sya_def[0]
|
||||||
|
|||||||
@@ -6,6 +6,22 @@ from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
|||||||
|
|
||||||
|
|
||||||
class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def execution_definition(context, service, concepts_map, definition):
|
||||||
|
if ">>" in definition:
|
||||||
|
a = concepts_map[definition.split(">>")[0].strip()]
|
||||||
|
return service.set_is_greatest(context, "prop_name", a)
|
||||||
|
if "<<" in definition:
|
||||||
|
a = concepts_map[definition.split("<<")[0].strip()]
|
||||||
|
return service.set_is_lesser(context, "prop_name", a)
|
||||||
|
if ">" in definition:
|
||||||
|
a, b = [concepts_map[e.strip()] for e in definition.split(">")]
|
||||||
|
return service.set_is_greater_than(context, "prop_name", a, b)
|
||||||
|
if "<" in definition:
|
||||||
|
a, b = [concepts_map[e.strip()] for e in definition.split("<")]
|
||||||
|
return service.set_is_less_than(context, "prop_name", a, b)
|
||||||
|
|
||||||
def test_i_can_add_a_is_greater_than(self):
|
def test_i_can_add_a_is_greater_than(self):
|
||||||
sheerka, context, one, two = self.init_concepts("one", "two", cache_only=False)
|
sheerka, context, one, two = self.init_concepts("one", "two", cache_only=False)
|
||||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
@@ -83,22 +99,34 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
|||||||
(["one < two"], {'1001': 1, '1002': 2}),
|
(["one < two"], {'1001': 1, '1002': 2}),
|
||||||
(["three > two", "one < two"], {'1001': 1, '1002': 2, '1003': 3}),
|
(["three > two", "one < two"], {'1001': 1, '1002': 2, '1003': 3}),
|
||||||
(["three > one", "one < two"], {'1001': 1, '1002': 2, '1003': 2}),
|
(["three > one", "one < two"], {'1001': 1, '1002': 2, '1003': 2}),
|
||||||
|
(["three >>"], {'1003': 2}),
|
||||||
|
(["one <<"], {'1001': 0}),
|
||||||
])
|
])
|
||||||
def test_i_can_get_concept_weight(self, entries, expected):
|
def test_i_can_get_concept_weight(self, entries, expected):
|
||||||
sheerka, context, *concepts = self.init_concepts("one", "two", "three")
|
sheerka, context, *concepts = self.init_concepts("one", "two", "three")
|
||||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
concepts_map = dict(zip(["one", "two", "three", "four", "five", "six"], concepts))
|
concepts_map = dict(zip(["one", "two", "three"], concepts))
|
||||||
|
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if ">" in entry:
|
self.execution_definition(context, service, concepts_map, entry)
|
||||||
a, b = [concepts_map[e.strip()] for e in entry.split(">")]
|
|
||||||
service.set_is_greater_than(context, "prop_name", a, b)
|
|
||||||
else:
|
|
||||||
a, b = [concepts_map[e.strip()] for e in entry.split("<")]
|
|
||||||
service.set_is_less_than(context, "prop_name", a, b)
|
|
||||||
|
|
||||||
assert service.get_concepts_weights("prop_name") == expected
|
assert service.get_concepts_weights("prop_name") == expected
|
||||||
|
|
||||||
|
def test_i_can_get_concept_weight_when_no_comparison_is_defined(self):
|
||||||
|
sheerka, context = self.init_concepts()
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
assert service.get_concepts_weights("prop_name") == {}
|
||||||
|
|
||||||
|
def test_i_can_recover_from_deleted_weight(self):
|
||||||
|
sheerka, context, one = self.init_concepts("one")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_lesser(context, "prop_name", one)
|
||||||
|
sheerka.cache_manager.clear(service.RESOLVED_COMPARISON_ENTRY)
|
||||||
|
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 0}
|
||||||
|
|
||||||
def test_i_can_get_partition(self):
|
def test_i_can_get_partition(self):
|
||||||
sheerka, context, one, two, three = self.init_concepts("one", "two", "three")
|
sheerka, context, one, two, three = self.init_concepts("one", "two", "three")
|
||||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
@@ -134,9 +162,6 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
|||||||
service.set_is_greater_than(context, "prop_name", four, three)
|
service.set_is_greater_than(context, "prop_name", four, three)
|
||||||
service.set_is_greater_than(context, "prop_name", five, two)
|
service.set_is_greater_than(context, "prop_name", five, two)
|
||||||
|
|
||||||
res = service.set_is_greater_than(context, "prop_name", two, one)
|
|
||||||
assert res.status
|
|
||||||
|
|
||||||
res = service.set_is_greater_than(context, "prop_name", one, five)
|
res = service.set_is_greater_than(context, "prop_name", one, five)
|
||||||
|
|
||||||
assert not res.status
|
assert not res.status
|
||||||
@@ -157,3 +182,156 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
|||||||
sheerka, context, one, two = self.init_concepts("one", "two")
|
sheerka, context, one, two = self.init_concepts("one", "two")
|
||||||
res = sheerka.set_is_greater_than(context, "prop_name", two, one)
|
res = sheerka.set_is_greater_than(context, "prop_name", two, one)
|
||||||
assert res.status
|
assert res.status
|
||||||
|
|
||||||
|
def test_a_lesser_concept_has_the_lowest_weight(self):
|
||||||
|
sheerka, context, one, two, three = self.init_concepts("one", "two", "three", cache_only=False)
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_lesser(context, "prop_name", one)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 0} # DEFAULT_COMPARISON_VALUE - 1
|
||||||
|
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", three, two)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 0, "1002": 1, "1003": 2}
|
||||||
|
|
||||||
|
# I can commit
|
||||||
|
sheerka.cache_manager.commit(context)
|
||||||
|
in_db = sheerka.sdp.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#")
|
||||||
|
assert in_db == [
|
||||||
|
ComparisonObj(context.event.get_digest(), "prop_name", one.id, None, "<<", "#"),
|
||||||
|
ComparisonObj(context.event.get_digest(), "prop_name", three.id, two.id, ">", "#")
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_i_can_define_an_order_for_lesser_concepts(self):
|
||||||
|
sheerka, context, lesser, less_l, even_more_l = self.init_concepts("lesser", "less_l", "even_less_l")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_lesser(context, "prop_name", lesser)
|
||||||
|
service.set_is_lesser(context, "prop_name", less_l)
|
||||||
|
service.set_is_lesser(context, "prop_name", even_more_l)
|
||||||
|
|
||||||
|
sheerka.set_is_less_than(context, "prop_name", less_l, lesser)
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", less_l, even_more_l)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 0, "1002": -1, "1003": -2}
|
||||||
|
|
||||||
|
def test_i_cannot_define_less_than_a_lesser_if_not_a_lesser_itself(self):
|
||||||
|
"""
|
||||||
|
minus_one cannot be defined as less that one is one is defined as lesser
|
||||||
|
unless minus_one is defined as lesser itself
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
sheerka, context, lesser, foo = self.init_concepts("lesser", "foo")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_lesser(context, "prop_name", lesser)
|
||||||
|
|
||||||
|
res = sheerka.set_is_less_than(context, "prop_name", foo, lesser)
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_LESSER_OPERATION)
|
||||||
|
|
||||||
|
res = sheerka.set_is_greater_than(context, "prop_name", foo, lesser)
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_LESSER_OPERATION)
|
||||||
|
|
||||||
|
def test_a_greatest_concept_has_the_highest_weight(self):
|
||||||
|
sheerka, context, one, two, three = self.init_concepts("one", "two", "three")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_greatest(context, "prop_name", three)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1003": 2} # DEFAULT_COMPARISON_VALUE + 1
|
||||||
|
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", two, one)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 1, "1002": 2, "1003": 3}
|
||||||
|
|
||||||
|
def test_i_cannot_define_greater_than_a_greatest_if_not_a_greater_itself(self):
|
||||||
|
sheerka, context, greatest, foo = self.init_concepts("greatest", "foo")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_greatest(context, "prop_name", greatest)
|
||||||
|
|
||||||
|
res = sheerka.set_is_less_than(context, "prop_name", foo, greatest)
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION)
|
||||||
|
|
||||||
|
res = sheerka.set_is_greater_than(context, "prop_name", foo, greatest)
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("definitions, expected", [
|
||||||
|
(["foo >>", "foo <<"], BuiltinConcepts.INVALID_GREATEST_OPERATION),
|
||||||
|
(["foo <<", "foo >>"], BuiltinConcepts.INVALID_LESSER_OPERATION),
|
||||||
|
])
|
||||||
|
def test_i_cannot_define_a_concept_as_lesser_and_greatest_at_the_same_time(self, definitions, expected):
|
||||||
|
sheerka, context, foo = self.init_concepts("foo")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
concepts_map = {"foo": foo}
|
||||||
|
|
||||||
|
self.execution_definition(context, service, concepts_map, definitions[0])
|
||||||
|
res = self.execution_definition(context, service, concepts_map, definitions[1])
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, expected)
|
||||||
|
|
||||||
|
def test_i_can_define_an_order_for_greatest_concepts(self):
|
||||||
|
sheerka, context, greatest, more_g, even_more_g = self.init_concepts("greatest", "more_g", "even_more_g")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_greatest(context, "prop_name", greatest)
|
||||||
|
service.set_is_greatest(context, "prop_name", more_g)
|
||||||
|
service.set_is_greatest(context, "prop_name", even_more_g)
|
||||||
|
|
||||||
|
sheerka.set_is_less_than(context, "prop_name", greatest, more_g)
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", even_more_g, more_g)
|
||||||
|
assert service.get_concepts_weights("prop_name") == {"1001": 2, "1002": 3, "1003": 4}
|
||||||
|
|
||||||
|
def test_i_can_mix_all_comparisons(self):
|
||||||
|
sheerka, context, one, two, three, four, five, six, three_and_half = self.init_concepts(
|
||||||
|
"one", "two", "three", "four", "five", "six", "two_and_half")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
|
||||||
|
service.set_is_lesser(context, "prop_name", one)
|
||||||
|
service.set_is_lesser(context, "prop_name", two)
|
||||||
|
sheerka.set_is_less_than(context, "prop_name", one, two)
|
||||||
|
|
||||||
|
service.set_is_greatest(context, "prop_name", five)
|
||||||
|
service.set_is_greatest(context, "prop_name", six)
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", six, five)
|
||||||
|
|
||||||
|
sheerka.set_is_less_than(context, "prop_name", three, four)
|
||||||
|
|
||||||
|
assert service.get_concepts_weights("prop_name") == {
|
||||||
|
"1001": -1,
|
||||||
|
"1002": 0,
|
||||||
|
"1003": 1,
|
||||||
|
"1004": 2,
|
||||||
|
"1005": 3,
|
||||||
|
"1006": 4
|
||||||
|
}
|
||||||
|
|
||||||
|
sheerka.set_is_less_than(context, "prop_name", three_and_half, four)
|
||||||
|
sheerka.set_is_greater_than(context, "prop_name", three_and_half, three)
|
||||||
|
|
||||||
|
assert service.get_concepts_weights("prop_name") == {
|
||||||
|
"1001": -1,
|
||||||
|
"1002": 0,
|
||||||
|
"1003": 1,
|
||||||
|
"1007": 2,
|
||||||
|
"1004": 3,
|
||||||
|
"1005": 4,
|
||||||
|
"1006": 5
|
||||||
|
}
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("definition", [
|
||||||
|
"one >>",
|
||||||
|
"one <<",
|
||||||
|
"one > two",
|
||||||
|
"one < two",
|
||||||
|
])
|
||||||
|
def test_i_cannot_add_the_same_definition_twice(self, definition):
|
||||||
|
sheerka, context, *concepts = self.init_concepts("one", "two")
|
||||||
|
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||||
|
concepts_map = dict(zip(["one", "two"], concepts))
|
||||||
|
|
||||||
|
self.execution_definition(context, service, concepts_map, definition)
|
||||||
|
res = self.execution_definition(context, service, concepts_map, definition)
|
||||||
|
|
||||||
|
assert not res.status
|
||||||
|
assert sheerka.isinstance(res.body, BuiltinConcepts.ALREADY_DEFINED)
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
|||||||
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
|
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||||
|
|
||||||
assert not res.status
|
assert not res.status
|
||||||
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED)
|
||||||
assert res.value.body == concept
|
assert res.value.body == concept
|
||||||
|
|
||||||
def test_i_can_get_a_newly_created_concept(self):
|
def test_i_can_get_a_newly_created_concept(self):
|
||||||
@@ -244,7 +244,7 @@ class TestSheerkaCreateNewConceptFileBased(TestUsingFileBasedSheerka):
|
|||||||
res = sheerka.create_new_concept(context, concept)
|
res = sheerka.create_new_concept(context, concept)
|
||||||
|
|
||||||
assert not res.status
|
assert not res.status
|
||||||
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED)
|
||||||
assert res.value.body == concept
|
assert res.value.body == concept
|
||||||
|
|
||||||
def test_new_entry_does_not_override_the_previous_ones(self):
|
def test_new_entry_does_not_override_the_previous_ones(self):
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
|
|||||||
res = sheerka.modify_concept(context, foo)
|
res = sheerka.modify_concept(context, foo)
|
||||||
|
|
||||||
assert not res.status
|
assert not res.status
|
||||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
assert sheerka.isinstance(res.body, BuiltinConcepts.ALREADY_DEFINED)
|
||||||
|
|
||||||
def test_i_can_modify_a_concept_that_is_in_a_list(self):
|
def test_i_can_modify_a_concept_that_is_in_a_list(self):
|
||||||
sheerka, context, foo1, foo2 = self.init_concepts(
|
sheerka, context, foo1, foo2 = self.init_concepts(
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ as:
|
|||||||
|
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert not res[0].status
|
assert not res[0].status
|
||||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
assert sheerka.isinstance(res[0].value, BuiltinConcepts.ALREADY_DEFINED)
|
||||||
|
|
||||||
@pytest.mark.parametrize("text", [
|
@pytest.mark.parametrize("text", [
|
||||||
"",
|
"",
|
||||||
@@ -891,16 +891,17 @@ as:
|
|||||||
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2, '1003': 3, '1004': 4}
|
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2, '1003': 3, '1004': 4}
|
||||||
|
|
||||||
def test_i_can_evaluate_expression_when_using_token_concept(self):
|
def test_i_can_evaluate_expression_when_using_token_concept(self):
|
||||||
sheerka, context, one, two, plus = self.init_concepts(
|
sheerka, context, one, two, three, is_less_than = self.init_concepts(
|
||||||
Concept("one", body="1"),
|
Concept("one", body="1"),
|
||||||
Concept("two", body="2"),
|
Concept("two", body="2"),
|
||||||
|
Concept("three", body="3"),
|
||||||
self.from_def_concept("<", "a < b", ["a", "b"], body="set_is_less_than('some_prop', a, b)")
|
self.from_def_concept("<", "a < b", ["a", "b"], body="set_is_less_than('some_prop', a, b)")
|
||||||
)
|
)
|
||||||
|
|
||||||
expression = "c:one: < c:two:"
|
expression = "c:one: < c:two:"
|
||||||
res = sheerka.evaluate_user_input(expression)
|
res = sheerka.evaluate_user_input(expression)
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].body == CMV(plus, a="c:one:", b="c:two:")
|
assert res[0].body == CMV(is_less_than, a="c:one:", b="c:two:")
|
||||||
assert res[0].body.a == NotInit # concept is not evaluated
|
assert res[0].body.a == NotInit # concept is not evaluated
|
||||||
assert res[0].body.b == NotInit # concept is not evaluated
|
assert res[0].body.b == NotInit # concept is not evaluated
|
||||||
|
|
||||||
@@ -911,11 +912,11 @@ as:
|
|||||||
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2}
|
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2}
|
||||||
|
|
||||||
# it now also works using the concepts names
|
# it now also works using the concepts names
|
||||||
expression = "eval one < two"
|
expression = "eval two < three"
|
||||||
res = sheerka.evaluate_user_input(expression)
|
res = sheerka.evaluate_user_input(expression)
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
||||||
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2}
|
assert sheerka.get_concepts_weights("some_prop") == {'1001': 1, '1002': 2, '1003': 3}
|
||||||
|
|
||||||
def test_i_can_detect_multiple_errors_when_evaluating_a_concept(self):
|
def test_i_can_detect_multiple_errors_when_evaluating_a_concept(self):
|
||||||
sheerka, context, foo, plus_one = self.init_concepts(
|
sheerka, context, foo, plus_one = self.init_concepts(
|
||||||
|
|||||||
Reference in New Issue
Block a user