Source code for fosf.parsers.taxonomy

#!/usr/bin/env python3
from collections import defaultdict

import networkx as nx
from lark import Lark

from fosf.config import FOSF_GRAMMAR
from fosf.parsers.base import BaseOSFParser
from fosf.parsers.graph import _GraphTransformer
from fosf.parsers.similarity import _SimilarityTransformer
from fosf.syntax.similarity import SubsumptionSimilarityTaxonomy
from fosf.syntax.taxonomy import FuzzySortTaxonomy, SortTaxonomy


class _TaxonomyTransformer(_GraphTransformer, _SimilarityTransformer):
    def __init__(self):
        super().__init__()
        self._instances = defaultdict(dict)

    def baseinstance(self, tree):
        return tree[0].value, 1.0

    def fuzzyinstance(self, tree):
        degree = float(tree[0].value)
        instance = tree[1].value
        return instance, degree

    def instance(self, tree):
        return tree[0]

    def instances(self, tree):
        return tree

    def instance_dec(self, tree):
        instances = tree[0]
        sorts = tree[1]
        for instance, degree in instances:
            for sort in sorts:
                self._instances[instance][sort] = degree

    def taxonomy_declarations(self, _) -> SortTaxonomy:
        if self.sim:
            subsumption = nx.DiGraph()
            subsumption.add_weighted_edges_from(
                (u, v, weight) for u, v, weight in self.decs
            )
            similarity = nx.Graph()
            similarity.add_weighted_edges_from(self.sim)
            return SubsumptionSimilarityTaxonomy(
                subsumption, similarity, instances=self._instances, keep_base=self._keep
            )
        if self.fuzzy:
            return FuzzySortTaxonomy(self.decs, instances=self._instances)
        return SortTaxonomy(self.decs, instances=self._instances)

    def transform(self, parse_tree, keep_base_subsumption=False):
        self.decs = []
        self.sim = []
        self.fuzzy = False
        self._keep = keep_base_subsumption
        return super().transform(parse_tree)


[docs] class TaxonomyParser(BaseOSFParser): def __init__(self): self.parser = Lark.open_from_package( "fosf", FOSF_GRAMMAR, start="taxonomy_declarations" ) self.transformer = _TaxonomyTransformer()
[docs] def parse(self, expression: str, keep_base_subsumption=False) -> SortTaxonomy: parse_tree = self.parser.parse(expression) return self.transformer.transform(parse_tree, keep_base_subsumption)