https://github.com/RichardMoot/LinearOne
Raw File
Tip revision: 19e8ca582fefc402aa015572e5d47d583cd44a10 authored by Richard Moot on 18 October 2016, 19:42:33 UTC
Added portray simplication for appl/2 with up to five arguments
Tip revision: 19e8ca5
lexicon.pl
:- module(lexicon, [lookup/4, lookup/5, macro_expand/2, lexical_lookup/5, lex_to_displacement/2, lex_to_hybrid/3,canonical_semantic_term/2]).

:- use_module(translations, [translate/3, translate_hybrid/6,linear_to_hybrid/3,linear_to_displacement/3]).
:- use_module(auxiliaries, [universal_closure/2,universal_disclosure/2, is_ll1_formula/2]).

% define operators to allow for easier specification of
% hybrid and displacement lexical entries.
%
% WARNING: in case of doubt, use parentheses to disambiguate!
% I have deliberately not changed the definitions of standard
% mathematical and logical operations of Prolog, notably |
% (alternative of ; for use in DCG), \ and *.
%
% This means for example that:
% c/d*b/c = ((c/d)*b)/c
% which corresponds to a left-to-right evaluation of the
% mathematical functions of division and multiplication.
% However, we do have the familiar a/b/c = (a/b)/c and
% c\b\a = (c\(b\a) and even a\b/c = (a\b)/c.

:- op(400, xfy, \).
:- op(400, xfy, \>).  % = \downarrow_>
:- op(400, yfx, />).  % = \uparrow_>
:- op(400, xfy, \<).  % = \downarrow_<
:- op(400, yfx, /<).  % = \uparrow_>
:- op(400, yfx, *<).  % = \odot_<
:- op(400, yfx, *>).  % = \odot_>
:- op(400, fx, ^).
:- op(190, yfx, @).

:- dynamic hybrid_lookup/3, memo_lookup/2.

lookup(Words, Formulas, Goal, ExpandedGoal) :-
	lookup(Words, Formulas, _, Goal, ExpandedGoal).

lookup(Words, Formulas, Semantics, Goal0, ExpandedGoal) :-
	retractall(hybrid_lookup(_, _, _)),
	sentence_lookup(Words, Formulas, Semantics, 0, N),
	macro_expand(Goal0, Goal),
	translate(Goal, [0, N], ExpandedGoal).

sentence_lookup([], [], [], N, N).
sentence_lookup([W|Ws], [F|Fs], [N0-S|Ss], N0, N) :-
        N1 is N0 + 1,
	lexical_lookup(W, F, S, N0, N1),
	sentence_lookup(Ws, Fs, Ss, N1, N).

lexical_lookup(Word, Formula, Semantics, N0, N1) :-
    (
	current_predicate(lex/3),	
	lex(Word, _, _)
    ->	     
        /* Lambek/Displacement entry */
	lex(Word, Formula0, Semantics0),
	canonical_semantic_term(Semantics0, Semantics),    
	macro_expand(Formula0, Formula1),
        translate(Formula1, [N0,N1], Formula),
        retractall(memo_lookup(N0, _)),
        assert(memo_lookup(N0, Word))
    ;
	current_predicate(lex/4),	
        lex(Word, _, _, _)
    ->
        /* hybrid entry */
        lex(Word, Formula0, ProsTerm0, Semantics0),
	/* prevent potential errors caused by accidental sharing of variables between ProsTerm and Semantics0 */
	copy_term(ProsTerm0, ProsTerm),
	canonical_semantic_term(Semantics0, Semantics),    
	macro_expand(Formula0, Formula1),
        translate_hybrid(Formula1, ProsTerm, Word, N0, N1, Formula),
	retractall(hybrid_lookup(N0, _, _)),
	assert(hybrid_lookup(N0, Formula1, ProsTerm))
    ;
        /* first-order linear logic entry */
	current_predicate(lex/5),	
        lex(Word, _, _, _, _)
    ->
	lex(Word, Formula0, N0, N1, Semantics0),
	macro_expand(Formula0, Formula),
	is_ll1_formula(Formula, Word),
	/* prevent potential errors caused by accidental sharing of variables between ProsTerm and Semantics0 */
	canonical_semantic_term(Semantics0, Semantics)
    ;
        format(user_error, '~N{Error: No lexical entry for "~w"}~n', [Word]),
        fail
    ).

lex_to_displacement(Word, Formula) :-
	lexical_lookup(Word, MFormula, _, 1, 2),
	universal_closure(MFormula, CFormula),
	linear_to_displacement(CFormula, [1,2], Formula).
lex_to_hybrid(Word, Formula, Term) :-
	lexical_lookup(Word, MFormula, _, 1, 2),
	universal_disclosure(MFormula, FFormula),
%	MFormula = FFormula,
	linear_to_hybrid(FFormula, Formula, Term).

macro_expand(F0, F) :-
	current_predicate(macro/2),
	macro(F0, F1),
	!,
	macro_expand(F1, F).
macro_expand(d_q, F) :-
	!,
	macro_expand(((s/<n)\<s)/cn, F).
macro_expand(d_tv, F) :-
	!,
	macro_expand((n\s)/n, F).
macro_expand(d_vp, F) :-
	!,
	macro_expand(n\s, F).
macro_expand(h_det, F) :-
	!,
	macro_expand(((s|(s|np))|n), F).
macro_expand(h_det_c, F) :-
	!,
	macro_expand(((s|(s|np(_)))|n), F).
macro_expand(tv, dr(dl(at(np),at(s)),at(np))) :-
	!.
macro_expand(vp, dl(at(np),at(s))) :-
	!.
macro_expand(tv_c, dr(dl(at(np, [nom]),at(s)),at(np, [acc]))) :-
	!.
macro_expand(vp_c, dl(at(np, [nom]),at(s))) :-
	!.
macro_expand(F, Formula) :-
	current_predicate(user:atomic_formula/3),
	user:atomic_formula(F, At, Vars),
	!,
   (
	is_list(Vars)
   ->	
        Formula = at(At, Vars)
   ;
        Formula = at(At, [Vars])
   ).
macro_expand(A0, A) :-
	atom(A0),
	!,
   (
	current_predicate(user:atomic_formula/3),
        user:atomic_formula(F, A0, _Vars)
   ->
        format(user_error, '~N{Warning: atomic formula used as "~w" but declared as "~w"}~n', [A0,F])
   ;
        true
   ),
	A = at(A0).
macro_expand(at(A), at(A)) :-
	!.
macro_expand(at(A,B), at(A,B)) :-
	!.

macro_expand(forall(X,A0), forall(X,A)) :-
	!,
	macro_expand(A0, A).
macro_expand(exists(X,A0), exists(X,A)) :-
	!,
	macro_expand(A0, A).
macro_expand(impl(A0,B0), impl(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).

macro_expand(p(K,A0,B0), p(K,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(dl(K,A0,B0), dl(K,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(dr(K,A0,B0), dr(K,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).

macro_expand((A0*B0), p(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(p(A0,B0), p(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).

macro_expand((A0\B0), dl(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(dl(A0,B0), dl(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).

macro_expand((A0/B0), dr(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(dr(A0,B0), dr(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).


macro_expand((A0\<B0), dl(<,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0\>B0), dl(>,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0/<B0), dr(<,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0/>B0), dr(>,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0*<B0), p(<,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0*>B0), p(>,A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(^A0, bridge(A)) :-
	!,
	macro_expand(A0, A).
macro_expand(bridge(A0), bridge(A)) :-
	!,
	macro_expand(A0, A).
macro_expand(lproj(A0), lproj(A)) :-
	!,
	macro_expand(A0, A).
macro_expand(rproj(A0), rproj(A)) :-
	!,
	macro_expand(A0, A).

macro_expand((B0->A0), h(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand((A0|B0), h(A,B)) :-
	!,
	macro_expand(A0, A),
	macro_expand(B0, B).
macro_expand(Formula, Formula) :-
	!,
	functor(Formula, F, A),
	functor(Term, F, A),
	format('~N{Warning: unknown formula ~w with functor ~w/~d}~n', [Formula, F, A]),
    (
	current_predicate(user:atomic_formula/3),
	user:atomic_formula(Atomic, F, _),
        functor(Atomic, F, A0)
    ->
	format('~N{Warning: did you mean ~w/~d?}~n', [F, A0])
    ;		  
        format('{Warning: you have to declare atomic formulas explicitly with: atomic_formula(~p).}~n', [Term])
    ),
        fail.

in_lexicon(W) :-
	lex(W, _, _).
in_lexicon(W) :-
	lex(W, _, _, _).


canonical_semantic_term(Term0, Term) :-
	copy_term(Term0, Term1),
	canonical_semantics(Term1, Term).

canonical_semantics(X, Z) :-
	var(X),
	!,
	Z = X.
canonical_semantics(X0@Y0, appl(X,Y)) :-
	!,
	canonical_semantics(X0, X),
	canonical_semantics(Y0, Y).
canonical_semantics(X^Y0, lambda(X,Y)) :-
	!,
	canonical_semantics(Y0, Y).
canonical_semantics(Term0, Term) :-
	Term0 =.. [F|List0],
	length(List0, L),
	length(List, L),
	Term =.. [F|List],
	canonical_semantics_list(List0, List).

canonical_semantics_list([], []).
canonical_semantics_list([X|Xs], [Y|Ys]) :-
	canonical_semantics(X, Y),
	canonical_semantics_list(Xs, Ys).
back to top