Introduced ConceptsAlgebra

This commit is contained in:
2020-09-27 20:28:50 +02:00
parent 978e5a5939
commit d100b7e8b3
18 changed files with 541 additions and 50 deletions
+8 -11
View File
@@ -1,4 +1,6 @@
#import admin
# define numbers
def concept one as 1
def concept two as 2
def concept three as 3
@@ -75,12 +77,13 @@ set_isa(one hundred, number)
def concept hundreds from bnf number=n1 'hundred' 'and' number=n2 where n1 < 10 and n2 < 100 as n1 * 100 + n2
set_isa(hundreds, number)
def concept hundreds from bnf number 'hundred' where number < 10 as number * 100
last_created_concept() is number
set_isa(last_created_concept(), number)
def concept thousands from bnf number 'thousand' where number < 1000 as number * 1000
set_isa(thousands, number)
def concept thousands from bnf number=n1 'thousand' 'and' number=n2 as n1 * 1000 + n2 where n1 < 1000 and n2 < 1000
last_created_concept() is number
def concept history as history()
set_isa(last_created_concept(), number)
# define basic operations on numbers
def concept plus from a plus 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
@@ -89,11 +92,5 @@ set_is_greater_than(__PRECEDENCE, multiplied, plus)
set_is_greater_than(__PRECEDENCE, divided, plus)
set_is_greater_than(__PRECEDENCE, multiplied, minus)
set_is_greater_than(__PRECEDENCE, divided, minus)
def concept precedence a > precedence b as set_is_greater_than(__PRECEDENCE, a, b)
set_isa(c:precedence a > precedence b:, __AUTO_EVAL)
def concept x is a command as set_isa(x, __AUTO_EVAL)
set_isa(c:x is a command:, __AUTO_EVAL)
def concept q from q ? as question(q) pre is_question()
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()
+28 -2
View File
@@ -5,8 +5,34 @@ set_isa(c:explain:, __AUTO_EVAL)
def concept explain last as get_last_results() | filter("id == 0") | recurse(2)
set_isa(c:explain last:, __AUTO_EVAL)
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 isinstance(x, int)
set_isa(c:explain x:, __AUTO_EVAL)
def concept explain x values where x as get_results() | filter(f"id=={x}") | format_d
def concept explain x values where isinstance(x, int) as get_results() | filter(f"id=={x}") | format_d
set_isa(c:explain x values:, __AUTO_EVAL)
def concept precedence a > precedence b as set_is_greater_than(__PRECEDENCE, a, b)
set_isa(c:precedence a > precedence b:, __AUTO_EVAL)
def concept x is a command as set_auto_eval(x, __AUTO_EVAL)
set_auto_eval(c:x is a command:)
def concept q from q ? as question(q) pre is_question()
set_is_lesser(__PRECEDENCE, q)
set_auto_eval(c:q:)
def concept "x is a concept" as isinstance(x, Concept) pre is_question()
def concept x is a y as set_isa(x, y)
set_auto_eval(c:x is a y:)
def concept x is an y as set_isa(x, y)
set_auto_eval(c:x is an y:)
def concept x is a y as isa(x,y) pre is_question()
def concept x is an y as isa(x,y) pre is_question()
def concept x has a y as set_hasa(x, y)
set_auto_eval(c:x has a y:)
def concept x has an y as set_hasa(x, y)
set_auto_eval(c:x has an y:)
def concept x has a y as hasa(x,y) pre is_question()
def concept x has an y as hasa(x,y) pre is_question()
+1 -2
View File
@@ -6,5 +6,4 @@ def concept apple
def concept table
def concept location
def concept x is on y as set_attr(x, location, y)
def concept x is a y as set_isa(x, y)
def concept x is a y as isa(x, y) pre is_question()
+32 -2
View File
@@ -53,6 +53,7 @@ class BuiltinConcepts(Enum):
# builtin attributes
ISA = "is a" # when a concept is an instance of another one
HASA = "has a" # when a concept has/owns another concept
AUTO_EVAL = "auto eval" # when the concept must be auto evaluated
# object
@@ -74,7 +75,8 @@ class BuiltinConcepts(Enum):
IS_EMPTY = "is empty" # when a set is empty
NO_RESULT = "no result" # no return value returned
INVALID_RETURN_VALUE = "invalid return value" # the return value of an evaluator is not correct
ALREADY_DEFINED = "already defined" # when you try to add the same object twice (a concept or whatever)
CONCEPT_ALREADY_DEFINED = "concept already defined" # when you try to add the same object twice (a concept or whatever)
PROPERTY_ALREADY_DEFINED = "property already defined" # When you try to add the same element in a property
NOP = "no operation" # no operation concept. Does nothing
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
ENUMERATION = "enum" # represents a list or a set
@@ -171,7 +173,8 @@ BuiltinErrors = [str(e) for e in {
BuiltinConcepts.TOO_MANY_ERRORS,
BuiltinConcepts.MULTIPLE_ERRORS,
BuiltinConcepts.INVALID_RETURN_VALUE,
BuiltinConcepts.ALREADY_DEFINED,
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
BuiltinConcepts.PROPERTY_ALREADY_DEFINED,
BuiltinConcepts.CONCEPT_EVAL_ERROR,
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
BuiltinConcepts.NOT_A_SET,
@@ -479,6 +482,33 @@ class ConceptAlreadyInSet(Concept):
return self.get_value("concept_set")
class PropertyAlreadyDefined(Concept):
def __init__(self, property_name=None, property_value=None, concept=None):
super().__init__(BuiltinConcepts.PROPERTY_ALREADY_DEFINED,
True,
False,
BuiltinConcepts.PROPERTY_ALREADY_DEFINED)
self.set_value(ConceptParts.BODY, property_name)
self.set_value("property_value", property_value)
self.set_value("concept", concept)
self.metadata.is_evaluated = True
def __repr__(self):
return f"PropertyAlreadyDefined(property={self.property_name}, value={self.property_value}, concept={self.concept})"
@property
def property_name(self):
return self.body
@property
def property_value(self):
return self.get_value("property_value")
@property
def concept(self):
return self.get_value("concept")
class ConditionFailed(Concept):
def __init__(self, condition=None, concept=None, prop=None):
super().__init__(BuiltinConcepts.CONDITION_FAILED,
+16 -16
View File
@@ -565,7 +565,7 @@ class Sheerka(Concept):
return c
metadata = [(index_name, key), ("id", concept_id)] if concept_id else (index_name, key)
return self._get_unknown(metadata)
return self.get_unknown(metadata)
def resolve(self, concept):
"""
@@ -827,20 +827,20 @@ class Sheerka(Concept):
return self.parsers_prefix + name
def concepts(self):
"""
List of all known concepts (look up in sdp)
:return:
"""
res = []
lst = self.sdp.list(self.CONCEPTS_BY_ID_ENTRY)
for item in lst:
if isinstance(item, list):
res.extend(item)
else:
res.append(item)
return sorted(res, key=lambda i: int(i.id))
# def concepts(self):
# """
# List of all known concepts (look up in sdp)
# :return:
# """
# res = []
# lst = self.sdp.list(self.CONCEPTS_BY_ID_ENTRY)
# for item in lst:
# if isinstance(item, list):
# res.extend(item)
# else:
# res.append(item)
#
# return sorted(res, key=lambda i: int(i.id))
def get_last_execution(self):
return self._last_execution
@@ -896,7 +896,7 @@ class Sheerka(Concept):
return a.key == b_key
@staticmethod
def _get_unknown(metadata):
def get_unknown(metadata):
"""
Returns the concept 'UnknownConcept' for a requested id or key
Note that I don't call the new() method to prevent cyclic call
@@ -139,7 +139,7 @@ class SheerkaComparisonManager(BaseService):
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))
return self.sheerka.ret(self.NAME, False, self.sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED))
new.append(comparison_obj)
@@ -0,0 +1,194 @@
from dataclasses import dataclass
from operator import attrgetter
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, ensure_concept
from core.sheerka.Sheerka import Sheerka
from core.sheerka.services.sheerka_service import BaseService
PROPERTIES_TO_COMPUTE = [BuiltinConcepts.ISA, BuiltinConcepts.HASA]
@dataclass
class ConceptScore:
"""
Concept a score, relative to concept b
"""
score: float
a: Concept
b: Concept
class SheerkaConceptsAlgebra(BaseService):
NAME = "ConceptsAlgebra"
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self.cadd, False)
self.sheerka.bind_service_method(self.csub, False)
self.sheerka.bind_service_method(self.recognize, False)
def cadd(self, context, *concepts):
"""
Concepts addition
Returns a concept with the union of some properties
:param context:
:param concepts:
:return:
"""
ensure_concept(*concepts)
res = Concept()
for c in concepts:
for prop in PROPERTIES_TO_COMPUTE:
self.add_props(res, c, prop)
return res
def csub(self, context, *concepts):
"""
Concepts subtraction
returns a concept where the properties of the first concept are removed if they appear in the other concepts
:param context:
:param concepts:
:return:
"""
res = Concept()
ensure_concept(*concepts)
if len(concepts) == 0:
return res # ? really
# init res
for prop in PROPERTIES_TO_COMPUTE:
self.add_props(res, concepts[0], prop)
for concept in concepts[1:]:
for prop in PROPERTIES_TO_COMPUTE:
self.sub_props(res, concept, prop)
return res
def add_props(self, destination, source, key):
"""
Add prop 'key', from source to destination
:param destination:
:param source:
:param key:
:return:
"""
if key not in source.metadata.props:
return
if key in destination.metadata.props:
destination.metadata.props[key].update(source.metadata.props[key])
else:
destination.metadata.props[key] = source.metadata.props[key].copy()
def sub_props(self, destination, source, key):
"""
Remove the property from destination if it exists in source
:param destination:
:param source:
:param key:
:return:
"""
if key not in source.metadata.props or key not in destination.metadata.props:
return
for item in source.metadata.props[key]:
destination.metadata.props[key].discard(item)
def recognize(self, concept, all_scores=False):
"""
Go thru all known concepts and try to recognize the properties
:param concept:
:param all_scores: returns all positive scores if true, returns the top one otherwise
:return:
"""
res = []
nb_props = self._count_props_values(concept)
if nb_props == 0:
return res
all_concepts = self.sheerka.cache_manager.copy(Sheerka.CONCEPTS_BY_ID_ENTRY).values() \
if self.sheerka.cache_manager.cache_only else self.sheerka.concepts()
for c in all_concepts:
score = self._compute_score(c, concept, step_b=round(1 / nb_props, 2))
if score > 0:
res.append(ConceptScore(score, c, concept))
if len(res) == 0:
props = []
for p in [p for p in PROPERTIES_TO_COMPUTE if p in concept.metadata.props]:
props.append((p, concept.metadata.props[p]))
return self.sheerka.get_unknown(props)
res.sort(key=attrgetter('score'), reverse=True)
if all_scores:
return res
to_keep = [res[0]]
max_score = res[0].score
i = 1
while i < len(res) and res[i].score == max_score:
to_keep.append(res[i])
i += 1
return to_keep if len(to_keep) > 1 else to_keep[0]
@staticmethod
def _compute_score(a, b, step_a=None, step_b=None):
"""
Compute a's score, compared to b properties
:param a:
:param b:
:param step_a:
:param step_b:
:return:
"""
score = 0
# adds step_b for every property that are in both a and b
for prop in PROPERTIES_TO_COMPUTE:
if prop in b.metadata.props and prop in a.metadata.props:
for prop_value in b.metadata.props[prop]:
if prop_value in a.metadata.props[prop]:
score += step_b
if not step_a:
concept_a_nb_props = SheerkaConceptsAlgebra._count_props_values(a)
if concept_a_nb_props == 0:
return score
step_b = round(1.0 / concept_a_nb_props, 2)
# remove step_a for every property that is in a, but not in b
for prop in PROPERTIES_TO_COMPUTE:
if prop in a.metadata.props and prop not in a.metadata.props:
score += step_a * len(a.metadata.props)
elif prop in a.metadata.props and prop in a.metadata.props:
for prop_value in a.metadata.props[prop]:
if prop_value not in b.metadata.props[prop]:
score -= step_b
return score
@staticmethod
def _count_props_values(concept):
"""
Count the number of values
:param concept:
:return:
"""
nb_props = 0
for prop in PROPERTIES_TO_COMPUTE:
if prop in concept.metadata.props:
nb_props += len(concept.metadata.props[prop])
return nb_props
@@ -44,7 +44,7 @@ class SheerkaCreateNewConcept(BaseService):
return sheerka.ret(
self.NAME,
False,
sheerka.new(BuiltinConcepts.ALREADY_DEFINED, body=concept),
sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
error.args[0])
# set id before saving in db
@@ -0,0 +1,53 @@
from core.builtin_concepts import BuiltinConcepts
from core.concept import ensure_concept
from core.sheerka.services.sheerka_service import BaseService
class SheerkaHasAManager(BaseService):
NAME = "HasAManager"
def __init__(self, sheerka):
super().__init__(sheerka)
def initialize(self):
self.sheerka.bind_service_method(self.set_hasa, True)
self.sheerka.bind_service_method(self.hasa, True)
def set_hasa(self, context, concept_a, concept_b):
"""
Defines that concept has/owns another concept
:param context:
:param concept_a:
:param concept_b:
:return:
"""
context.log(f"Setting concept {concept_a} has a {concept_b}", who=self.NAME)
ensure_concept(concept_a, concept_b)
if (BuiltinConcepts.HASA in concept_a.metadata.props and
concept_b in concept_a.metadata.props[BuiltinConcepts.HASA]):
return self.sheerka.ret(
self.NAME,
False,
self.sheerka.new(BuiltinConcepts.PropertyAlreadyDefined,
body=concept_b,
name=BuiltinConcepts.HASA,
concept=concept_a))
concept_a.add_prop(BuiltinConcepts.HASA, concept_b)
return self.sheerka.modify_concept(context, concept_a)
def hasa(self, concept_a, concept_b):
"""
Check that concept 'a' has/owns concept 'b'
:param context:
:param concept_a:
:param concept_b:
:return:
"""
ensure_concept(concept_a, concept_b)
return (BuiltinConcepts.HASA in concept_a.metadata.props and
concept_b in concept_a.metadata.props[BuiltinConcepts.HASA])
@@ -44,7 +44,7 @@ class SheerkaModifyConcept(BaseService):
return self.sheerka.ret(
self.NAME, False,
self.sheerka.new(
BuiltinConcepts.ALREADY_DEFINED,
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
body=concept))
self.sheerka.cache_manager.update_concept(old_version, concept)
@@ -197,7 +197,7 @@ class SheerkaSetsManager(BaseService):
for c in a.metadata.props[BuiltinConcepts.ISA]:
if c == b:
return True
if self.isa(c, b):
if self.isa(self.sheerka.get_by_id(c.id), b):
return True
return False
+1 -1
View File
@@ -334,4 +334,4 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
res = self.execution_definition(context, service, concepts_map, definition)
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.ALREADY_DEFINED)
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
+175
View File
@@ -0,0 +1,175 @@
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaConceptsAlgebra import ConceptScore
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
class TestSheerkaConceptsAlgebra(TestUsingMemoryBasedSheerka):
def test_i_can_add_concepts(self):
sheerka, context, man, human, male, driver, licence, car = self.init_concepts(
"man", "human", "male",
"driver", "licence", "car")
sheerka.set_isa(context, sheerka.new("man"), human)
sheerka.set_isa(context, sheerka.new("man"), male)
sheerka.set_hasa(context, sheerka.new("driver"), licence)
sheerka.set_hasa(context, sheerka.new("driver"), car)
res = sheerka.cadd(context, sheerka.new("man"), sheerka.new("driver"))
assert isinstance(res, Concept)
assert res.metadata.props == {BuiltinConcepts.ISA: {male, human},
BuiltinConcepts.HASA: {car, licence}, }
def test_can_add_concepts_when_property_already_exist(self):
sheerka, context, man, human, king, male = self.init_concepts(
"man", "human", "king", "male")
sheerka.set_isa(context, sheerka.new("man"), human)
sheerka.set_isa(context, sheerka.new("king"), male)
res = sheerka.cadd(context, sheerka.new("man"), sheerka.new("king"))
assert isinstance(res, Concept)
assert res.metadata.props == {BuiltinConcepts.ISA: {male, human}}
def test_i_can_subtract_concepts(self):
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
"foo", "bar",
"isa1", "isa2", "has1", "has2")
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_isa(context, new_foo, isa2)
sheerka.set_hasa(context, new_foo, hasa1)
sheerka.set_hasa(context, new_foo, hasa2)
new_bar = sheerka.new("bar")
sheerka.set_isa(context, new_bar, isa1)
sheerka.set_hasa(context, new_bar, hasa1)
assert sheerka.csub(context) == Concept()
res = sheerka.csub(context, new_foo)
assert isinstance(res, Concept)
assert res.metadata.props == res.metadata.props
res = sheerka.csub(context, new_foo, new_bar)
assert isinstance(res, Concept)
assert res.metadata.props == {BuiltinConcepts.ISA: {isa2},
BuiltinConcepts.HASA: {hasa2}, }
def test_i_can_recognize_myself_when_cache_only_is_not_set(self):
sheerka, context, foo, isa1, hasa1, = self.init_concepts("foo", "isa1", "has1",
cache_only=False,
create_new=True)
sheerka.cache_manager.commit(context)
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_hasa(context, new_foo, hasa1)
sheerka.cache_manager.commit(context)
assert sheerka.recognize(new_foo, all_scores=True) == [ConceptScore(1, new_foo, new_foo)]
def test_i_can_recognize_myself_when_cache_only_is_set(self):
sheerka, context, foo, isa1, hasa1, = self.init_concepts("foo", "isa1", "has1")
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_hasa(context, new_foo, hasa1)
assert sheerka.recognize(new_foo, all_scores=True) == [ConceptScore(1, new_foo, new_foo)]
def test_unknown_prop_is_returned_when_nothing_is_recognized(self):
sheerka, context, isa1, hasa1, = self.init_concepts("isa1", "has1")
foo = Concept()
foo.add_prop(BuiltinConcepts.ISA, isa1)
foo.add_prop(BuiltinConcepts.HASA, hasa1)
res = sheerka.recognize(foo, all_scores=True)
assert sheerka.isinstance(res, BuiltinConcepts.UNKNOWN_CONCEPT)
assert res.body == [(BuiltinConcepts.ISA, {isa1}), (BuiltinConcepts.HASA, {hasa1})]
def test_empty_list_is_return_when_there_is_noting_to_recognize(self):
sheerka, context = self.init_concepts()
assert sheerka.recognize(Concept(), all_scores=True) == []
def test_i_can_recognize_multiple_concepts_with_the_proper_score(self):
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
"foo", "bar",
"isa1", "isa2", "has1", "has2")
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_isa(context, new_foo, isa2)
sheerka.set_hasa(context, new_foo, hasa1)
sheerka.set_hasa(context, new_foo, hasa2)
new_bar = sheerka.new("bar")
sheerka.set_isa(context, new_bar, isa1)
sheerka.set_hasa(context, new_bar, hasa1)
to_recognize = Concept()
to_recognize.add_prop(BuiltinConcepts.ISA, isa1)
to_recognize.add_prop(BuiltinConcepts.HASA, hasa1)
res = sheerka.recognize(to_recognize, all_scores=True)
assert res == [ConceptScore(1.0, sheerka.new("bar"), to_recognize),
ConceptScore(0.5, sheerka.new("foo"), to_recognize)]
# add the other properties, to match foo
to_recognize.add_prop(BuiltinConcepts.ISA, isa2)
to_recognize.add_prop(BuiltinConcepts.HASA, hasa2)
res = sheerka.recognize(to_recognize, all_scores=True)
assert res == [ConceptScore(1.0, sheerka.new("foo"), to_recognize),
ConceptScore(0.5, sheerka.new("bar"), to_recognize)]
def test_i_can_recognize_if_all_scores_is_disabled(self):
sheerka, context, foo, bar, isa1, isa2, hasa1, hasa2 = self.init_concepts(
"foo", "bar",
"isa1", "isa2", "has1", "has2")
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_isa(context, new_foo, isa2)
sheerka.set_hasa(context, new_foo, hasa1)
sheerka.set_hasa(context, new_foo, hasa2)
new_bar = sheerka.new("bar")
sheerka.set_isa(context, new_bar, isa1)
sheerka.set_hasa(context, new_bar, hasa1)
to_recognize = Concept()
to_recognize.add_prop(BuiltinConcepts.ISA, isa1)
to_recognize.add_prop(BuiltinConcepts.HASA, hasa1)
res = sheerka.recognize(to_recognize, all_scores=False)
assert res == ConceptScore(1.0, sheerka.new("bar"), to_recognize)
def test_i_can_recognize_if_all_scores_is_disabled_but_multiple_high_scores(self):
sheerka, context, foo, bar, isa1, hasa1 = self.init_concepts(
"foo", "bar",
"isa1", "has1")
new_foo = sheerka.new("foo")
sheerka.set_isa(context, new_foo, isa1)
sheerka.set_hasa(context, new_foo, hasa1)
new_bar = sheerka.new("bar")
sheerka.set_isa(context, new_bar, isa1)
sheerka.set_hasa(context, new_bar, hasa1)
to_recognize = Concept()
to_recognize.add_prop(BuiltinConcepts.ISA, isa1)
to_recognize.add_prop(BuiltinConcepts.HASA, hasa1)
res = sheerka.recognize(to_recognize, all_scores=False)
assert len(res) == 2
assert ConceptScore(1.0, sheerka.new("foo"), to_recognize) in res
assert ConceptScore(1.0, sheerka.new("bar"), to_recognize) in res
+2 -2
View File
@@ -99,7 +99,7 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED)
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
assert res.value.body == concept
def test_i_can_get_a_newly_created_concept(self):
@@ -260,7 +260,7 @@ class TestSheerkaCreateNewConceptFileBased(TestUsingFileBasedSheerka):
res = sheerka.create_new_concept(context, concept)
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED)
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
assert res.value.body == concept
def test_new_entry_does_not_override_the_previous_ones(self):
+17
View File
@@ -0,0 +1,17 @@
from core.builtin_concepts import BuiltinConcepts
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
class TestSheerkaHasAManager(TestUsingMemoryBasedSheerka):
def test_i_can_set_hasa(self):
sheerka, context, king, kingdom = self.init_concepts("king", "kingdom")
res = sheerka.set_hasa(context, sheerka.new("king"), kingdom)
assert res.status
another_king = sheerka.get_by_key("king")
assert another_king.get_prop(BuiltinConcepts.HASA) == {kingdom}
# check that the definition of the concept has been updated
assert sheerka.hasa(sheerka.new("king"), kingdom)
+1 -1
View File
@@ -73,7 +73,7 @@ class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
res = sheerka.modify_concept(context, foo)
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.ALREADY_DEFINED)
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
def test_i_can_modify_a_concept_that_is_in_a_list(self):
sheerka, context, foo1, foo2 = self.init_concepts(
+7 -7
View File
@@ -241,12 +241,12 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
Concept("baz"),
)
sheerka.set_isa(context, foo, bar)
sheerka.set_isa(context, bar, baz)
sheerka.set_isa(context, sheerka.new("foo"), bar)
sheerka.set_isa(context, sheerka.new("bar"), baz)
assert sheerka.isa(foo, bar)
assert sheerka.isa(bar, baz)
assert sheerka.isa(foo, baz)
assert sheerka.isa(sheerka.new("foo"), bar)
assert sheerka.isa(sheerka.new("bar"), baz)
assert sheerka.isa(sheerka.new("foo"), baz)
def test_i_cannot_manage_isa_transitivity_when_using_body(self):
sheerka, context, one, another_one, number = self.init_concepts(
@@ -255,9 +255,9 @@ class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
"number"
)
sheerka.set_isa(context, one, number)
sheerka.set_isa(context, sheerka.new("one"), number)
assert sheerka.isa(one, number) # sanity
assert sheerka.isa(sheerka.new("one"), number) # sanity
assert not sheerka.isa(another_one, number) # Correct this misbehaviour when BuiltinConcepts.IS is implemented
def test_concept_expression_recurse_id_is_updated(self):
+1 -1
View File
@@ -167,7 +167,7 @@ as:
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].value, BuiltinConcepts.ALREADY_DEFINED)
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
@pytest.mark.parametrize("text", [
"",