From 3c07573916e90481187b810da95e531ce0fcdfb1 Mon Sep 17 00:00:00 2001 From: haberchr Date: Fri, 3 Nov 2023 18:18:09 -0700 Subject: [PATCH] Subclass referents to make quantifiers, create universe with itertools --- src/examples/learn_quant/grammar.py | 2 +- src/examples/learn_quant/grammar.yml | 6 +- src/examples/learn_quant/index.csv | 12 +-- src/examples/learn_quant/meaning.py | 20 +++- src/examples/learn_quant/pertinence.csv | 5 - src/examples/learn_quant/quantifier.py | 93 +++++++++++++++++++ .../scripts/generate_expressions.py | 12 +-- .../learn_quant/scripts/generation_test.py | 2 +- 8 files changed, 122 insertions(+), 30 deletions(-) delete mode 100644 src/examples/learn_quant/pertinence.csv create mode 100644 src/examples/learn_quant/quantifier.py diff --git a/src/examples/learn_quant/grammar.py b/src/examples/learn_quant/grammar.py index 78039fb..bb6fd89 100644 --- a/src/examples/learn_quant/grammar.py +++ b/src/examples/learn_quant/grammar.py @@ -1,3 +1,3 @@ from altk.language.grammar import Grammar, Rule -quantifiers_grammar = Grammar.from_yaml("../grammar.yml") \ No newline at end of file +quantifiers_grammar = Grammar.from_yaml("learn_quant/grammar.yml") \ No newline at end of file diff --git a/src/examples/learn_quant/grammar.yml b/src/examples/learn_quant/grammar.yml index d637235..438166b 100644 --- a/src/examples/learn_quant/grammar.yml +++ b/src/examples/learn_quant/grammar.yml @@ -49,7 +49,7 @@ rules: - set name: "index" function: | - lambda i, s: set(x for x in s if x.index == i) + lambda i, s: sorted(s)[i] - lhs: int rhs: - set @@ -83,9 +83,9 @@ rules: rhs: name: "A" function: | - lambda point: point.pertinence in ['A', "both"] + lambda point: quantifier.A - lhs: set rhs: name: "B" function: | - lambda point: point.pertinence in ['B', "both"] \ No newline at end of file + lambda point: quantifier.B \ No newline at end of file diff --git a/src/examples/learn_quant/index.csv b/src/examples/learn_quant/index.csv index 39d2573..9a3ab50 100644 --- a/src/examples/learn_quant/index.csv +++ b/src/examples/learn_quant/index.csv @@ -1,7 +1,5 @@ -name -1 -2 -3 -4 -5 -6 +value +A +B +both +neither \ No newline at end of file diff --git a/src/examples/learn_quant/meaning.py b/src/examples/learn_quant/meaning.py index e6652ef..ef93f39 100644 --- a/src/examples/learn_quant/meaning.py +++ b/src/examples/learn_quant/meaning.py @@ -1,11 +1,21 @@ import pandas as pd from altk.language.semantics import Universe +from learn_quant.quantifier import QuantifierModel +from itertools import product -referent_index = pd.read_csv("../index.csv") -referent_pertinence = pd.read_csv("../pertinence.csv") +M_SIZE = 6 +referent_pertinence = pd.read_csv("learn_quant/index.csv").to_dict() -referents = referent_index.merge(referent_pertinence, how='cross') -referents.columns = ['name', 'pertinence'] +def create_universe(referent_pertinence, M_SIZE): -universe = Universe.from_dataframe(referents) + quantifier_names = [] + for size in range(M_SIZE+1): + index = [i for i in range(len(referent_pertinence["value"]))] + x_universe = product("".join([str(x) for x in index]), repeat=size) + quantifier_names.extend(["".join(array) for array in x_universe]) + + return Universe([QuantifierModel(name) for name in quantifier_names if name != '']) +quantifiers_universe = create_universe(referent_pertinence, M_SIZE) + +print(len(quantifiers_universe)) \ No newline at end of file diff --git a/src/examples/learn_quant/pertinence.csv b/src/examples/learn_quant/pertinence.csv deleted file mode 100644 index 3f30c48..0000000 --- a/src/examples/learn_quant/pertinence.csv +++ /dev/null @@ -1,5 +0,0 @@ -name -neither -A -B -both \ No newline at end of file diff --git a/src/examples/learn_quant/quantifier.py b/src/examples/learn_quant/quantifier.py new file mode 100644 index 0000000..bfeacc6 --- /dev/null +++ b/src/examples/learn_quant/quantifier.py @@ -0,0 +1,93 @@ + +from typing import Iterable, Union +import numpy as np +import pandas as pd +from altk.language.semantics import Referent +from dataclasses import dataclass + +@dataclass +class QuantifierModel(Referent): + """A quantifier model is a single referent that captures a particular interpretation of a quantifier meaning, which is a set of quantifier referents.""" + + name: str() = None + M: set() = None + A: set() = None + B: set() = None + + def __post_init__(self): + + if not self.name and not (self.M and self.A and self.B): + raise ValueError("Must initialize with either a name or sets for ") + + if self.M and self.A and self.B: + self._update_name() + + elif self.name: + self._update_sets() + + def _update_sets(self, name=None): + + if name: + self.name = name + + self.M = set() + self.A = set() + self.B = set() + for index, i in enumerate(self.name): + self.M.add(int(index)) + if self.name[index] == "0": + self.A.add(int(index)) + if self.name[index] == "1": + self.B.add(int(index)) + if self.name[index] == "2": + self.A.add(int(index)) + self.B.add(int(index)) + + def _update_name(self, M=None, A=None, B=None): + + if M: + self.M = M + if A: + self.A = A + if B: + self.B = B + + name_seq = [] + for i in sorted(self.M): + i_in_both = i in self.A and i in self.B + i_in_A = i in self.A and not i_in_both + i_in_B = i in self.B and not i_in_both + i_in_neither = (not i_in_A) and (not i_in_B) + if i_in_A: + name_seq.append("0") + if i_in_B: + name_seq.append("1") + if i_in_both: + name_seq.append("2") + if i_in_neither: + name_seq.append("3") + self.name = "".join(name_seq) + + def update(self, **kwargs): + + self.__dict__.update((key, kwargs[key]) + for key in ('name', 'M', 'A', 'B') if key in kwargs) + self._update_name() + self._update_sets() + + def get_cardinalities(self) -> dict: + return {"A": len(self.A), "B": len(self.B), "M": len(self.M)} + +""" +qm = QuantifierModel(M=set([1,2,3,4]), A=set([1,4]), B=set([2,3])) +qm.name + +qm2 = QuantifierModel("0030") +qm2.A = None +qm2.A +qm2._update_sets("1111") +qm2._update_sets("0011") + +qm3 = QuantifierModel("13022") +qm3 +""" \ No newline at end of file diff --git a/src/examples/learn_quant/scripts/generate_expressions.py b/src/examples/learn_quant/scripts/generate_expressions.py index 21efca3..b15d3cd 100644 --- a/src/examples/learn_quant/scripts/generate_expressions.py +++ b/src/examples/learn_quant/scripts/generate_expressions.py @@ -5,21 +5,17 @@ except ImportError: from yaml import Dumper -from examples.learn_quant.grammar import quantifiers_grammar -from examples.learn_quant.meaning import universe as quantifiers_universe - -import os -print(os.getcwd()) +from ..grammar import quantifiers_grammar +from ..meaning import quantifiers_universe if __name__ == "__main__": expressions_by_meaning = quantifiers_grammar.get_unique_expressions( - 5, + 1, max_size=2 ** len(quantifiers_universe), unique_key=lambda expr: expr.evaluate(quantifiers_universe), compare_func=lambda e1, e2: len(e1) < len(e2), ) - print(quantifiers_universe) # filter out the trivial meaning, results in NaNs # iterate over keys, since we need to change the dict itself @@ -27,7 +23,7 @@ if len(meaning.referents) == 0: del expressions_by_meaning[meaning] - with open("../outputs/generated_expressions.yml", "w") as outfile: + with open("learn_quant/outputs/generated_expressions.yml", "w+") as outfile: dump( [ expressions_by_meaning[meaning].to_dict() diff --git a/src/examples/learn_quant/scripts/generation_test.py b/src/examples/learn_quant/scripts/generation_test.py index 35ffdd4..3b1e286 100644 --- a/src/examples/learn_quant/scripts/generation_test.py +++ b/src/examples/learn_quant/scripts/generation_test.py @@ -6,7 +6,7 @@ from yaml import Dumper from examples.learn_quant.grammar import quantifiers_grammar -from examples.learn_quant.meaning import universe as quantifiers_universe +from examples.learn_quant.meaning import quantifiers_universe if __name__ == "__main__": quantifiers_grammar.generate()