Skip to content

Prolog Compiler

Bases: Compiler

A Compiler that generates Prolog code from a Theory object.

Source code in src/typedlogic/compilers/prolog_compiler.py
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
@dataclass
class PrologCompiler(Compiler):
    """A Compiler that generates Prolog code from a Theory object."""

    default_suffix: ClassVar[str] = "pro"
    config: Optional[PrologConfig] = None

    def compile(self, theory: Theory, syntax: Optional[Union[str, ModelSyntax]] = None, **kwargs) -> str:
        """
        Compile a Theory object into Prolog code.

        Example:
        -------
            >>> from typedlogic import *
            >>> theory = Theory()
            >>> x = Variable("x")
            >>> theory.predicate_definitions = [PredicateDefinition("P", {"x": "str"}),
            ...              PredicateDefinition("Q", {"x": "str"})]
            >>> s = Implies(Term("P", x), Term("Q", x))
            >>> theory.add(sentence=s)
            >>> compiler = PrologCompiler()
            >>> print(compiler.compile(theory))
            %% Predicate Definitions
            % P(x: str)
            % Q(x: str)
            <BLANKLINE>
            %% Sentences
            <BLANKLINE>
            q(X) :- p(X).

        :param theory:
        :param syntax:
        :param kwargs:
        :return:

        """
        config = self.config
        if self.config is None:
            config = PrologConfig(**kwargs)
        lines = []
        lines.append("%% Predicate Definitions")
        for pd in theory.predicate_definitions:
            args = ", ".join([f"{k}: {v}" for k, v in pd.arguments.items()])
            lines.append(f"% {pd.predicate}({args})")
        for sg in theory.sentence_groups:
            lines.append(f"\n%% {sg.name}\n")
            for s in sg.sentences or []:
                try:
                    lines.append(as_prolog(s, config, translate=True))
                except NotInProfileError as e:
                    self._add_untranslatable(s)
                    fol = as_fol(s)
                    fol = fol.replace("\n", " ")
                    lines.append(f"%% UNTRANSLATABLE: {fol}")
                    if self.strict:
                        raise e
        return "\n".join(lines)

compile(theory, syntax=None, **kwargs)

Compile a Theory object into Prolog code.

Example:

>>> from typedlogic import *
>>> theory = Theory()
>>> x = Variable("x")
>>> theory.predicate_definitions = [PredicateDefinition("P", {"x": "str"}),
...              PredicateDefinition("Q", {"x": "str"})]
>>> s = Implies(Term("P", x), Term("Q", x))
>>> theory.add(sentence=s)
>>> compiler = PrologCompiler()
>>> print(compiler.compile(theory))
%% Predicate Definitions
% P(x: str)
% Q(x: str)
<BLANKLINE>
%% Sentences
<BLANKLINE>
q(X) :- p(X).

Parameters:

Name Type Description Default
theory Theory
required
syntax Optional[Union[str, ModelSyntax]]
None
kwargs
{}

Returns:

Type Description
str
Source code in src/typedlogic/compilers/prolog_compiler.py
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
def compile(self, theory: Theory, syntax: Optional[Union[str, ModelSyntax]] = None, **kwargs) -> str:
    """
    Compile a Theory object into Prolog code.

    Example:
    -------
        >>> from typedlogic import *
        >>> theory = Theory()
        >>> x = Variable("x")
        >>> theory.predicate_definitions = [PredicateDefinition("P", {"x": "str"}),
        ...              PredicateDefinition("Q", {"x": "str"})]
        >>> s = Implies(Term("P", x), Term("Q", x))
        >>> theory.add(sentence=s)
        >>> compiler = PrologCompiler()
        >>> print(compiler.compile(theory))
        %% Predicate Definitions
        % P(x: str)
        % Q(x: str)
        <BLANKLINE>
        %% Sentences
        <BLANKLINE>
        q(X) :- p(X).

    :param theory:
    :param syntax:
    :param kwargs:
    :return:

    """
    config = self.config
    if self.config is None:
        config = PrologConfig(**kwargs)
    lines = []
    lines.append("%% Predicate Definitions")
    for pd in theory.predicate_definitions:
        args = ", ".join([f"{k}: {v}" for k, v in pd.arguments.items()])
        lines.append(f"% {pd.predicate}({args})")
    for sg in theory.sentence_groups:
        lines.append(f"\n%% {sg.name}\n")
        for s in sg.sentences or []:
            try:
                lines.append(as_prolog(s, config, translate=True))
            except NotInProfileError as e:
                self._add_untranslatable(s)
                fol = as_fol(s)
                fol = fol.replace("\n", " ")
                lines.append(f"%% UNTRANSLATABLE: {fol}")
                if self.strict:
                    raise e
    return "\n".join(lines)