git @ Cat's Eye Technologies Lome / master src / lome / term.py
master

Tree @master (Download .tar.gz)

term.py @masterraw · history · blame

# Copyright (c) 2025-2026, Chris Pressey, Cat's Eye Technologies.
# This file is distributed under a 2-clause BSD license.  See LICENSES/ dir.
# SPDX-License-Identifier: LicenseRef-BSD-2-Clause-X-Lome

from dataclasses import dataclass
from typing import List


@dataclass
class Ctor:
    symbol: str
    subterms: List['Term']


Term = Ctor


def is_variable(t: Term) -> bool:
    """Check if a term represents a variable (begins with uppercase letter)."""
    return isinstance(t, Ctor) and t.symbol.isupper()


def is_decoration(t: Term) -> bool:
    return isinstance(t, Ctor) and t.symbol.startswith('*')


def render_term(t: Term) -> str:
    if isinstance(t, Ctor):
        if t.subterms:
            return "{}({})".format(t.symbol, ', '.join([render_term(st) for st in t.subterms]))
        else:
            return t.symbol
    else:
        raise NotImplementedError(str(t))


def terms_equal(term1: Term, term2: Term) -> bool:
    if not isinstance(term1, Ctor) or not isinstance(term2, Ctor):
        return False
    if term1.symbol != term2.symbol:
        return False
    if term1.subterms is None and term2.subterms is None:
        return True
    if term1.subterms is None or term2.subterms is None:
        return False
    if len(term1.subterms) != len(term2.subterms):
        return False
    return all(terms_equal(sub1, sub2) for sub1, sub2 in zip(term1.subterms, term2.subterms))


def strip_decorators(term: Term) -> Term:
    if not isinstance(term, Ctor):
        return term
    if is_decoration(term):
        return strip_decorators(term.subterms[0])
    elif term.subterms:
        return Ctor(term.symbol, [strip_decorators(subterm) for subterm in term.subterms])
    else:
        return term