Source code for pydialogue.state.kn_checkers

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
This module contains the functions that check whether the information exists in the KnowledgeBase.
"""
import copy

from . import kn_helpers
from . import kn_parsers
from ..environment import entities as em
from ..language import sentences as tsentences


[docs] def basic_checker(kb_state, sent): """ Checks whether a sentence with the same meaning is present in the database. Parameters ---------- kb_state : KnowledgeBase The knowledge base that contains the set of truthful sentences. sent : Sentence This sentence is checked against the database. Returns ------- is_true : bool True is returned if the sentence is present False is returned if the sentence with the opposite meaning is present. None is returned if the sentence is not present. """ is_true = None if sent in kb_state.sent_db: is_true = True oppos_sent = kn_helpers.create_oppos_sent(sent) if oppos_sent in kb_state.sent_db: is_true = False return is_true
[docs] def property_checker(kb_state, sent): """ Checks whether the sentence is in one of the following forms: - <entity> 's <property_key> is <property_val> - <entity> is <attribute> and if so, extracts the arguments and calls the :func:`property_check_alt() <pydialogue.state.kn_checkers.property_check_alt>` function. The :func:`property_check_alt() <pydialogue.state.kn_checkers.property_check_alt>` checks whether the sentence is truthful and whether the information it conveys is visible to the agents. Parameters ---------- kb_state : KnowledgeBase The knowledge base that is used for testing the truthfulness of the sentence sent : Sentence The sentence that is checked. Returns ------- has_prop : bool or None Returns True if the sentence is truthful. Otherwise, False. If the information is not visible to the agent, None is returned regardless of the truthfulness of the sentence. """ has_prop = None mem = kn_helpers.check_prop(sent) if mem is not None: ent, pkey, pval, pneg = mem has_prop = property_alt_checker(kb_state, ent, pkey, pval, pneg) return has_prop
[docs] def property_alt_checker(kb_state, ent, pkey, pval, pneg): """ Checks whether the entity's (property_key, property_value) is the correct one and whether the property value is seen by the agent. Additionally, this function can be used to check whether the entity's attribute exists and whether is seen by the agent. Parameters ---------- kb_state : KnowledgeBase The kb_state.world is used for getting the most recent version of the entity (in case there are copies of the entity) ent : Entity The entity which property is checked. pkey : str or tuple or None The property key. If pkey is None, then the existence of an attribute is checked. pval : any The property value or the attribute. pneg : str or None pneg indicates whether to check for equality or inequality Returns ------- result : bool or None Returns True if the entity's pkey is pval and pneg is None or entity's pkey is not pval and pneg is not None. Otherwise, False is returned. If the information is not visible to the agent in the context, None is returned regardless of the truthfulness. """ if ((pkey is not None and not isinstance(pkey, str) and not isinstance(pkey, tuple)) or (pkey is None and not isinstance(pval, str) and not isinstance(pval, tuple))): return None world_ent = getattr(kb_state.world, ent.get_property("var_name"), None) if world_ent is None: return None result = None if pkey is not None: if pkey in world_ent.prop_seen: result = world_ent.prop_seen[pkey] == pval else: if pkey in world_ent.prop_seen_neg and pval in world_ent.prop_seen_neg[pkey]: result = False else: if pval in world_ent.attr_seen: result = True elif pval in world_ent.attr_seen_neg: result = False if result is not None: if pneg is not None and pneg in ['no', 'not']: result = not result return result
[docs] def multiple_prop_checker(kb_state, sent): mem = kn_helpers.check_prop(sent) if mem is not None: ent, pkey, pval, pneg = mem if isinstance(pval, set): list_eval = [] for val in pval: has_prop = property_alt_checker(kb_state, ent, pkey, val, pneg) list_eval.append(has_prop) if all(list_eval): return True elif False in list_eval: return False
[docs] def elem_exists_checker(kb_state, sent): """ Checks whether the sentence is in the form described in kn_parsers.elem_exists_parse and if so, extracts the arguments and calls the :func:`check_elem_exists_alt() <pydialogue.state.kn_checkers.check_elem_exists_alt>` function. The :func:`check_elem_exists_alt() <pydialogue.state.kn_checkers.check_elem_exists_alt>` checks whether the entity's element (property or attribute) exists and whether the existence is visible to the agents. Parameters ---------- kb_state : KnowledgeBase The knowledge base is used for testing the truthfulness of the sentence. sent : Sentence The sentence to check for truthfulness. Returns ------- elem_exists : bool or None Returns True if the sentence is truthful. Otherwise, False. If the information that the sentence conveys is not previously seen by the agent, None is returned regardless of the truthfulness. """ parsed = kn_parsers.elem_exists_parse(sent) elem_exists = None if parsed is not None: ent, elem, pneg = parsed elem_exists = elem_exists_alt_checker(kb_state, ent, elem, pneg) return elem_exists
[docs] def elem_exists_alt_checker(kb_state, ent, elem, pneg): """ Checks whether the entity's property key or attribute exists and is seen by the agent in the context. Parameters ---------- kb_state : KnowledgeBase The kb_state.world is used for getting the most recent version of the entity (in case a copy of the entity is provided) ent : Entity The entity whose element existence is checked. elem : str or tuple The property key or the attribute pneg : str or None pneg indicates whether to check for equality or inequality Returns ------- result : bool True if the element exists and pneg is None, or the element does not exist and pneg is not None. Otherwise, False is returned. If the element's existence is not seen by the agent in the context, None is returned. """ world_ent = getattr(kb_state.world, ent.get_property("var_name"), None) if world_ent is None: return None result = None if elem is not None: if (elem in world_ent.elem_exists or elem in world_ent.prop_seen or elem in world_ent.attr_seen): result = True elif elem in world_ent.elem_not_exists: result = False if result is not None and pneg is not None and pneg in ['no', 'not']: result = not result return result
[docs] def have_checker(kb_state, sent): """ Checks whether an object has items on/under/in it and whether the agent has seen this information. Parameters ---------- kb_state : KnowledgeBase The knowledge base is used to check the validity of the sentence. sent : Sentence The sentence has to be in the form described in kn_parsers.have_parse. Returns ------- is_true : bool or None True if the sentence is truthful. Otherwise, False. If the information that the sentence conveys is not seen by the agent, None is returned, regardless of the truthfulness of the sentence. """ is_true = None mem = kn_parsers.have_parse(sent) if mem is not None: owner, possession, neg, loc = mem if loc is None: loc = ['in', owner] results = [] if isinstance(owner, em.Entity): if possession == "items" and neg is not None and neg in ['no', 'not']: objs = kb_state.world.obj_list else: if possession is None: possession = [] elif isinstance(possession, set): possession = list(possession) elif not isinstance(possession, list): possession = [possession] objs = possession for obj in objs: if not isinstance(obj, em.Entity): return None res = property_alt_checker(kb_state, obj, "location", loc, neg) results.append(res) if len(results) > 0 and all(results): is_true = True elif False in results: is_true = False return is_true
[docs] def val_is_key_checker(kb_state, sent): """ Checks whether the agent has seen the following sentences in the meta context: .. <property_value> is (not) <property_key> or <str> is (not) direction. For example, "medium is not a color". """ if len(sent.describers) > 0: describer = sent.describers[0] arg_ppt = describer.get_arg("Arg-PPT") arg_prd = describer.get_arg("Arg-PRD") am_neg = describer.get_arg("AM-NEG") if (arg_ppt is None or arg_prd is None or sent != tsentences.be((arg_ppt, None), ("is", None), (am_neg, None), (arg_prd, None))): return None if isinstance(arg_prd, list): arg_prd = tuple(arg_prd) additional_prds = [('player', prop) for prop in ['name', 'nickname', 'surname']] if arg_prd not in kb_state.world.all_properties+['direction']+additional_prds: return None result = None all_keys = [] for obj in kb_state.world.obj_list: for key, val in obj.prop_seen.items(): if val == arg_ppt: all_keys.append(key) if len(all_keys) > 0: if am_neg == 'not': result = not (arg_prd in all_keys) elif am_neg is None: result = arg_prd in all_keys if result is None: result = basic_checker(kb_state, sent) return result