Skip to content

Commit

Permalink
Subclass referents to make quantifiers, create universe with itertools
Browse files Browse the repository at this point in the history
  • Loading branch information
haberchr committed Nov 4, 2023
1 parent ac25c5b commit 3c07573
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/examples/learn_quant/grammar.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from altk.language.grammar import Grammar, Rule

quantifiers_grammar = Grammar.from_yaml("../grammar.yml")
quantifiers_grammar = Grammar.from_yaml("learn_quant/grammar.yml")
6 changes: 3 additions & 3 deletions src/examples/learn_quant/grammar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -83,9 +83,9 @@ rules:
rhs:
name: "A"
function: |
lambda point: point.pertinence in ['A', "both"]
lambda point: quantifier.A

This comment has been minimized.

Copy link
@shanest

shanest Nov 4, 2023

Collaborator

I think this should be point.A

- lhs: set
rhs:
name: "B"
function: |
lambda point: point.pertinence in ['B', "both"]
lambda point: quantifier.B
12 changes: 5 additions & 7 deletions src/examples/learn_quant/index.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
name
1
2
3
4
5
6
value
A
B
both
neither
20 changes: 15 additions & 5 deletions src/examples/learn_quant/meaning.py
Original file line number Diff line number Diff line change
@@ -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()

This comment has been minimized.

Copy link
@shanest

shanest Nov 4, 2023

Collaborator

Prob don't need to even use index.csv given how limited it is; could just use an Enum for instance


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))
5 changes: 0 additions & 5 deletions src/examples/learn_quant/pertinence.csv

This file was deleted.

93 changes: 93 additions & 0 deletions src/examples/learn_quant/quantifier.py
Original file line number Diff line number Diff line change
@@ -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

This comment has been minimized.

Copy link
@shanest

shanest Nov 4, 2023

Collaborator

Nice! just str, set, etc w/o the parentheses for type annotations

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 <M, A, B>")

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
"""
12 changes: 4 additions & 8 deletions src/examples/learn_quant/scripts/generate_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,25 @@
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),

This comment has been minimized.

Copy link
@shanest

shanest Nov 4, 2023

Collaborator

the point.A comment could impact this :), since evaluate will prob throw an error w/ the lambdas as currently written if I'm understanding right

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
for meaning in list(expressions_by_meaning.keys()):
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()
Expand Down
2 changes: 1 addition & 1 deletion src/examples/learn_quant/scripts/generation_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 3c07573

Please sign in to comment.