home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum16.lzh
/
SOFTWARE
/
PROLOG
/
EXAMPLES
/
unify.pro
< prev
Wrap
Text File
|
1991-03-24
|
5KB
|
111 lines
/*
Testimplementierung eines Unifikationsalgorithmus in Prolog.
(UNIFY.PRO)
Autor: M. Moser
Datum: 16.7.90
Version: 1.0
Historie:
Version 1.0 am 16.7.90: Urversion
*/
/* Ein Term ist definiert als eine Konstante oder ein Term aus */
/* einem Funktor und einer Liste von Termen als Argumente. (Vgl. */
/* Terme in Prolog.) Zwei Terme s und t heissen unifizierbar, wenn */
/* es Substitutionen fuer die Variablen von s und t gibt, so dass s */
/* und t gleich werden. Eine Substitution fuer eine Variable x ist */
/* ein Paar x/u, wobei u der Term ist, durch den x ersetzt wird. */
/* Der Term u darf aber selbst die Variable x nicht enthalten, da */
/* sich sonst eine unendliche Einsetzung ergaebe. (Diese Situation */
/* wird auch als loop bezeichnet.) Stehen sich an entsprechenden */
/* Positionen von s und t zwei verschiedene Funktoren oder Konstan- */
/* ten gegenueber, dann scheitert die Unifikation an einem sog. */
/* clash, denn derartige Terme lassen sich durch Variablenerset- */
/* zugen nicht gleich machen. */
/* Eine Menge M von Substitutionen wird auf einen Term t angewen- */
/* det, indem gleichzeitig alle Variablen von t durch die entspre- */
/* chenden Terme aus M ersetzt werden. Die Anwendung von M auf t */
/* wird im weiteren als t M geschrieben. M ist ein Unifikator */
/* zweier Terme s und t, wenn s M = t M ist, also die Substitutio- */
/* nen in M die Terme s und t gleich machen. Ein allgemeinster */
/* Unifikator zweier Terme s und t ist schliesslich ein Unifika- */
/* tor M, so dass fuer jeden anderen Unifikator N von s und t gilt: */
/* Es gibt einen Unifikator M', so dass t M M' = t N. (Intuitiv */
/* gesprochen ist ein Unifikator genau dann ein allgemeinster Uni- */
/* fikator, wenn er moeglichst wenige Variablen durch moeglichst */
/* allgemeine Terme ersetzt. Ein Term ist um so weniger allgemein, */
/* je mehr Funktoren er enthaelt.) Ein allgemeinster Unifikator */
/* ist bis auf Variablenumbenennungen eindeutig. */
/* Beispiele: (Der Versuch, zwei Terme s und t zu unifizieren, */
/* wird unify(s, t) geschrieben.) */
/* unify(c, d) -> clash (zwei verschiedene Konstanten sind */
/* nicht unifizierbar) */
/* unify(x, c) -> { x/c } (mit einer Variable ist jeder Term */
/* unifizeribar, */
/* unify(x, f(x)) -> loop sofern er die Variable nicht ent- */
/* haelt!) */
/* unify(f(x, c), g(h(y), y)) */
/* -> { x/h(y), y/c } */
/* unify(x, y) -> { x/y } oder { y/x } */
/* Der folgende Algorithmus gestattet es, zusaetzlich zu den beiden */
/* Termen s und t noch eine Menge R bereits vorhandener Substitu- */
/* tionen anzugeben. Als Ergebnis der Unifikation wird bei unifi- */
/* zierbaren Termen eine Liste Q von Substitutionen geliefert, an- */
/* derenfalls scheitert das Praedikat unify. */
unify(S, T, R, Q) :-
deref(S, R, U), deref(T, R, V),
unifyterms(U, V, R, Q).
deref(S, [], S) :-
var(S).
deref(S, _, S) :-
nonvar(S).
deref(S, [bind(V, T) | R], T) :-
var(S), S == V.
deref(S, [bind(U, _) | R], T) :-
var(S), S \== U,
deref(S, R, T).
unifyterms(V, W, R, R) :-
var(V), var(W), V == W.
unifyterms(V, W, R, [bind(V, W) | R]) :-
var(V), var(W), V \== W.
unifyterms(V, T, R, [bind(V, T) | R]) :-
var(V), nonvar(T),
not occurs(V, T, R).
unifyterms(T, V, R, [bind(V, T) | R]) :-
nonvar(T), var(V),
not occurs(V, T, R).
unifyterms(S, T, R, Q) :-
nonvar(S), nonvar(T),
functor(S, F, N), functor(T, F, N),
unifyargs(N, S, T, R, Q).
unifyargs(0, S, S, R, R).
unifyargs(N, S, T, R, Q) :-
N > 0, M is N - 1, unifyargs(M, S, T, R, P),
arg(N, S, A), arg(N, T, B), unify(A, B, P, Q).
occurs(V, W, R) :-
var(V), var(W), V == W.
occurs(V, W, R) :-
var(V), var(W), V \== W,
bound(W, R, T), occurs(V, T, R).
occurs(V, T, R) :-
var(V), nonvar(T),
functor(T, F, N), occursinargs(N, V, T, R).
bound(V, R, T) :-
deref(V, R, T), V \== T.
occursinargs(N, V, T, R) :-
N > 0, M is N - 1, occursinargs(M, V, T, R)
;
arg(N, T, A), occurs(V, A, R).