File size: 2,665 Bytes
5027724
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from __future__ import annotations

from dataclasses import dataclass
import json
from pathlib import Path


@dataclass(frozen=True)
class QueryForm:
    intent: str
    prefix: tuple[str, ...]
    relation: str = ""
    relation_mode: str = "fixed"
    subject_mode: str = "tail"
    subject_start: int = 0
    subject_end_anchor: str = ""
    object_start_anchor: str = ""
    object_mode: str = "none"
    requires: tuple[str, ...] = ()


class NativeQueryFormSet:
    DEFAULT_PATH = Path(__file__).resolve().parents[1] / "data" / "native" / "query" / "aethon_query_forms_v1.json"

    def __init__(self, path: str | Path | None = None, payload: list[dict[str, object]] | None = None) -> None:
        self.path = Path(path) if path is not None else self.DEFAULT_PATH
        self.forms = self._load_forms(payload)

    def _load_forms(self, payload: list[dict[str, object]] | None) -> tuple[QueryForm, ...]:
        if payload is not None:
            return tuple(self._row_to_form(row) for row in payload)
        if not self.path.exists():
            return ()
        data = json.loads(self.path.read_text(encoding="utf-8"))
        return tuple(self._row_to_form(row) for row in data)

    @staticmethod
    def _row_to_form(row: dict[str, object]) -> QueryForm:
        return QueryForm(
            intent=str(row["intent"]).strip(),
            prefix=tuple(str(item).strip() for item in row.get("prefix", [])),
            relation=str(row.get("relation", "")).strip(),
            relation_mode=str(row.get("relation_mode", "fixed")).strip(),
            subject_mode=str(row.get("subject_mode", "tail")).strip(),
            subject_start=int(row.get("subject_start", 0)),
            subject_end_anchor=str(row.get("subject_end_anchor", "")).strip(),
            object_start_anchor=str(row.get("object_start_anchor", "")).strip(),
            object_mode=str(row.get("object_mode", "none")).strip(),
            requires=tuple(str(item).strip() for item in row.get("requires", [])),
        )

    def to_payload(self) -> list[dict[str, object]]:
        return [
            {
                "intent": form.intent,
                "prefix": list(form.prefix),
                "relation": form.relation,
                "relation_mode": form.relation_mode,
                "subject_mode": form.subject_mode,
                "subject_start": form.subject_start,
                "subject_end_anchor": form.subject_end_anchor,
                "object_start_anchor": form.object_start_anchor,
                "object_mode": form.object_mode,
                "requires": list(form.requires),
            }
            for form in self.forms
        ]