mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-26 07:33:47 +00:00
22bbf7ca22
* CONTRIBUTE,Makefile.in,configure.ac: Update to reflect test directory moves. * test/file-organisation.org: New file. * test/automated/Makefile.in test/automated/data/decompress/foo.gz test/automated/data/epg/pubkey.asc test/automated/data/epg/seckey.asc test/automated/data/files-bug18141.el.gz test/automated/data/flymake/test.c test/automated/data/flymake/test.pl test/automated/data/package/archive-contents test/automated/data/package/key.pub test/automated/data/package/key.sec test/automated/data/package/multi-file-0.2.3.tar test/automated/data/package/multi-file-readme.txt test/automated/data/package/newer-versions/archive-contents test/automated/data/package/newer-versions/new-pkg-1.0.el test/automated/data/package/newer-versions/simple-single-1.4.el test/automated/data/package/package-test-server.py test/automated/data/package/signed/archive-contents test/automated/data/package/signed/archive-contents.sig test/automated/data/package/signed/signed-bad-1.0.el test/automated/data/package/signed/signed-bad-1.0.el.sig test/automated/data/package/signed/signed-good-1.0.el test/automated/data/package/signed/signed-good-1.0.el.sig test/automated/data/package/simple-depend-1.0.el test/automated/data/package/simple-single-1.3.el test/automated/data/package/simple-single-readme.txt test/automated/data/package/simple-two-depend-1.1.el test/automated/abbrev-tests.el test/automated/auto-revert-tests.el test/automated/calc-tests.el test/automated/icalendar-tests.el test/automated/character-fold-tests.el test/automated/comint-testsuite.el test/automated/descr-text-test.el test/automated/electric-tests.el test/automated/cl-generic-tests.el test/automated/cl-lib-tests.el test/automated/eieio-test-methodinvoke.el test/automated/eieio-test-persist.el test/automated/eieio-tests.el test/automated/ert-tests.el test/automated/ert-x-tests.el test/automated/generator-tests.el test/automated/let-alist.el test/automated/map-tests.el test/automated/advice-tests.el test/automated/package-test.el test/automated/pcase-tests.el test/automated/regexp-tests.el test/automated/seq-tests.el test/automated/subr-x-tests.el test/automated/tabulated-list-test.el test/automated/thunk-tests.el test/automated/timer-tests.el test/automated/epg-tests.el test/automated/eshell.el test/automated/faces-tests.el test/automated/file-notify-tests.el test/automated/auth-source-tests.el test/automated/gnus-tests.el test/automated/message-mode-tests.el test/automated/help-fns.el test/automated/imenu-test.el test/automated/info-xref.el test/automated/mule-util.el test/automated/isearch-tests.el test/automated/json-tests.el test/automated/bytecomp-tests.el test/automated/coding-tests.el test/automated/core-elisp-tests.el test/automated/decoder-tests.el test/automated/files.el test/automated/font-parse-tests.el test/automated/lexbind-tests.el test/automated/occur-tests.el test/automated/process-tests.el test/automated/syntax-tests.el test/automated/textprop-tests.el test/automated/undo-tests.el test/automated/man-tests.el test/automated/completion-tests.el test/automated/dbus-tests.el test/automated/newsticker-tests.el test/automated/sasl-scram-rfc-tests.el test/automated/tramp-tests.el test/automated/obarray-tests.el test/automated/compile-tests.el test/automated/elisp-mode-tests.el test/automated/f90.el test/automated/flymake-tests.el test/automated/python-tests.el test/automated/ruby-mode-tests.el test/automated/subword-tests.el test/automated/replace-tests.el test/automated/simple-test.el test/automated/sort-tests.el test/automated/subr-tests.el test/automated/reftex-tests.el test/automated/sgml-mode-tests.el test/automated/tildify-tests.el test/automated/thingatpt.el test/automated/url-future-tests.el test/automated/url-util-tests.el test/automated/add-log-tests.el test/automated/vc-bzr.el test/automated/vc-tests.el test/automated/xml-parse-tests.el test/BidiCharacterTest.txt test/biditest.el test/cedet/cedet-utests.el test/cedet/ede-tests.el test/cedet/semantic-ia-utest.el test/cedet/semantic-tests.el test/cedet/semantic-utest-c.el test/cedet/semantic-utest.el test/cedet/srecode-tests.el test/cedet/tests/test.c test/cedet/tests/test.el test/cedet/tests/test.make test/cedet/tests/testdoublens.cpp test/cedet/tests/testdoublens.hpp test/cedet/tests/testfriends.cpp test/cedet/tests/testjavacomp.java test/cedet/tests/testnsp.cpp test/cedet/tests/testpolymorph.cpp test/cedet/tests/testspp.c test/cedet/tests/testsppcomplete.c test/cedet/tests/testsppreplace.c test/cedet/tests/testsppreplaced.c test/cedet/tests/testsubclass.cpp test/cedet/tests/testsubclass.hh test/cedet/tests/testtypedefs.cpp test/cedet/tests/testvarnames.c test/etags/CTAGS.good test/etags/ETAGS.good_1 test/etags/ETAGS.good_2 test/etags/ETAGS.good_3 test/etags/ETAGS.good_4 test/etags/ETAGS.good_5 test/etags/ETAGS.good_6 test/etags/a-src/empty.zz test/etags/a-src/empty.zz.gz test/etags/ada-src/2ataspri.adb test/etags/ada-src/2ataspri.ads test/etags/ada-src/etags-test-for.ada test/etags/ada-src/waroquiers.ada test/etags/c-src/a/b/b.c test/etags/c-src/abbrev.c test/etags/c-src/c.c test/etags/c-src/dostorture.c test/etags/c-src/emacs/src/gmalloc.c test/etags/c-src/emacs/src/keyboard.c test/etags/c-src/emacs/src/lisp.h test/etags/c-src/emacs/src/regex.h test/etags/c-src/etags.c test/etags/c-src/exit.c test/etags/c-src/exit.strange_suffix test/etags/c-src/fail.c test/etags/c-src/getopt.h test/etags/c-src/h.h test/etags/c-src/machsyscalls.c test/etags/c-src/machsyscalls.h test/etags/c-src/sysdep.h test/etags/c-src/tab.c test/etags/c-src/torture.c test/etags/cp-src/MDiagArray2.h test/etags/cp-src/Range.h test/etags/cp-src/burton.cpp test/etags/cp-src/c.C test/etags/cp-src/clheir.cpp.gz test/etags/cp-src/clheir.hpp test/etags/cp-src/conway.cpp test/etags/cp-src/conway.hpp test/etags/cp-src/fail.C test/etags/cp-src/functions.cpp test/etags/cp-src/screen.cpp test/etags/cp-src/screen.hpp test/etags/cp-src/x.cc test/etags/el-src/TAGTEST.EL test/etags/el-src/emacs/lisp/progmodes/etags.el test/etags/erl-src/gs_dialog.erl test/etags/f-src/entry.for test/etags/f-src/entry.strange.gz test/etags/f-src/entry.strange_suffix test/etags/forth-src/test-forth.fth test/etags/html-src/algrthms.html test/etags/html-src/index.shtml test/etags/html-src/software.html test/etags/html-src/softwarelibero.html test/etags/lua-src/allegro.lua test/etags/objc-src/PackInsp.h test/etags/objc-src/PackInsp.m test/etags/objc-src/Subprocess.h test/etags/objc-src/Subprocess.m test/etags/objcpp-src/SimpleCalc.H test/etags/objcpp-src/SimpleCalc.M test/etags/pas-src/common.pas test/etags/perl-src/htlmify-cystic test/etags/perl-src/kai-test.pl test/etags/perl-src/yagrip.pl test/etags/php-src/lce_functions.php test/etags/php-src/ptest.php test/etags/php-src/sendmail.php test/etags/prol-src/natded.prolog test/etags/prol-src/ordsets.prolog test/etags/ps-src/rfc1245.ps test/etags/pyt-src/server.py test/etags/tex-src/gzip.texi test/etags/tex-src/nonewline.tex test/etags/tex-src/testenv.tex test/etags/tex-src/texinfo.tex test/etags/y-src/atest.y test/etags/y-src/cccp.c test/etags/y-src/cccp.y test/etags/y-src/parse.c test/etags/y-src/parse.y test/indent/css-mode.css test/indent/js-indent-init-dynamic.js test/indent/js-indent-init-t.js test/indent/js-jsx.js test/indent/js.js test/indent/latex-mode.tex test/indent/modula2.mod test/indent/nxml.xml test/indent/octave.m test/indent/pascal.pas test/indent/perl.perl test/indent/prolog.prolog test/indent/ps-mode.ps test/indent/ruby.rb test/indent/scheme.scm test/indent/scss-mode.scss test/indent/sgml-mode-attribute.html test/indent/shell.rc test/indent/shell.sh test/redisplay-testsuite.el test/rmailmm.el test/automated/buffer-tests.el test/automated/cmds-tests.el test/automated/data-tests.el test/automated/finalizer-tests.el test/automated/fns-tests.el test/automated/inotify-test.el test/automated/keymap-tests.el test/automated/print-tests.el test/automated/libxml-tests.el test/automated/zlib-tests.el: Files Moved.
291 lines
9.7 KiB
Prolog
291 lines
9.7 KiB
Prolog
%% -*- mode: prolog; coding: utf-8; fill-column: 78 -*-
|
|
|
|
%% bug#21526
|
|
test21526_1 :-
|
|
( a ->
|
|
( a ->
|
|
b
|
|
; c
|
|
)
|
|
; % Toto
|
|
c ->
|
|
d
|
|
).
|
|
|
|
test21526_2 :-
|
|
( a
|
|
-> ( a,
|
|
b
|
|
; c
|
|
),
|
|
b2
|
|
; c1,
|
|
c2
|
|
).
|
|
|
|
test21526_3 :-
|
|
X \= Y,
|
|
\+ a,
|
|
b,
|
|
\+ \+ c,
|
|
d.
|
|
|
|
test21526_4 :-
|
|
( \+ a ->
|
|
b
|
|
; \+ c,
|
|
\+ d
|
|
).
|
|
|
|
|
|
test21526_5 :-
|
|
(a;
|
|
b ->
|
|
c).
|
|
|
|
test21526_predicate(c) :- !,
|
|
test_goal1,
|
|
test_goal2.
|
|
|
|
%% Testing correct tokenizing.
|
|
foo(X) :- 0'= = X.
|
|
foo(X) :- 8'234 = X.
|
|
foo(X) :- '\x45\' = X.
|
|
foo(X) :- 'test 0'=X.
|
|
foo(X) :- 'test 8'=X.
|
|
|
|
%% wf(+E)
|
|
%% Vérifie que E est une expression syntaxiquement correcte.
|
|
wf(X) :- atom(X); integer(X); var(X). %Une variable ou un entier.
|
|
wf(lambda(X, T, B)) :- atom(X), wf(T), wf(B). %Une fonction.
|
|
wf(app(E1, E2)) :- wf(E1), wf(E2). %Un appel de fonction.
|
|
wf(pi(X, T, B)) :- atom(X), wf(T), wf(B). %Le type d'une fonction.
|
|
|
|
%% Éléments additionnels utilisés dans le langage source.
|
|
wf(lambda(X, B)) :- atom(X), wf(B).
|
|
wf(let(X, E1, E2)) :- atom(X), wf(E1), wf(E2).
|
|
wf(let(X, T, E1, E2)) :- atom(X), wf(T), wf(E1), wf(E2).
|
|
wf((T1 -> T2)) :- wf(T1), wf(T2).
|
|
wf(forall(X, T, B)) :- atom(X), wf(T), wf(B).
|
|
wf(fix(X,T,E1,E2)) :- atom(X), wf(T), wf(E1), wf(E2).
|
|
wf(fix(X,E1,E2)) :- atom(X), wf(E1), wf(E2).
|
|
wf(app(E1,E2,E3)) :- wf(E1), wf(E2), wf(E3).
|
|
wf(app(E1,E2,E3,E4)) :- wf(E1), wf(E2), wf(E3), wf(E4).
|
|
|
|
%% subst(+X, +V, +FV, +Ei, -Eo)
|
|
%% Remplace X par V dans Ei. Les variables qui apparaissent libres dans
|
|
%% V et peuvent aussi apparaître dans Ei doivent toutes être inclues
|
|
%% dans l'environnement FV.
|
|
subst(X, V, _, X, E) :- !, E = V.
|
|
subst(_, _, _, Y, Y) :- atom(Y); integer(Y).
|
|
%% Residualize the substitution when applied to an uninstantiated variable.
|
|
%% subst(X, V, _, Y, app(lambda(X,_,Y),V)) :- var(Y).
|
|
%% Rather than residualize and leave us with unifications that fail, let's
|
|
%% rather assume that Y will not refer to X.
|
|
subst(X, V, _, Y, Y) :- var(Y).
|
|
subst(X, V, FV, lambda(Y, Ti, Bi), lambda(Y1, To, Bo)) :-
|
|
subst(X, V, FV, Ti, To),
|
|
(X = Y ->
|
|
%% If X is equal to Y, X is shadowed, so no subst can take place.
|
|
Y1 = Y, Bo = Bi;
|
|
(member((Y, _), FV) ->
|
|
%% If Y appears in FV, it can appear in V, so we need to
|
|
%% rename it to avoid name capture.
|
|
new_atom(Y, Y1),
|
|
subst(Y, Y1, [], Bi, Bi1);
|
|
Y1 = Y, Bi1 = Bi),
|
|
%% Perform substitution on the body.
|
|
subst(X, V, FV, Bi1, Bo)),
|
|
( X = Y
|
|
%% If X is equal to Y, X is shadowed, so no subst can take place.
|
|
-> Y1 = Y, Bo = Bi
|
|
; (member((Y, _), FV)
|
|
%% If Y appears in FV, it can appear in V, so we need to
|
|
%% rename it to avoid name capture.
|
|
-> new_atom(Y, Y1),
|
|
subst(Y, Y1, [], Bi, Bi1)
|
|
; Y1 = Y, Bi1 = Bi),
|
|
%% Perform substitution on the body.
|
|
subst(X, V, FV, Bi1, Bo)
|
|
).
|
|
subst(X, V, FV, pi(Y, Ti, Bi), pi(Y1, To, Bo)) :-
|
|
subst(X, V, FV, lambda(Y, Ti, Bi), lambda(Y1, To, Bo)).
|
|
subst(X, V, FV, forall(Y, Ti, Bi), forall(Y1, To, Bo)) :-
|
|
subst(X, V, FV, lambda(Y, Ti, Bi), lambda(Y1, To, Bo)).
|
|
subst(X, V, FV, app(E1i, E2i), app(E1o, E2o)) :-
|
|
subst(X, V, FV, E1i, E1o), subst(X, V, FV, E2i, E2o).
|
|
|
|
%% apply(+F, +Arg, +Env, -E)
|
|
apply(lambda(X, _, B), Arg, Env, E) :- \+ var(B), subst(X, Arg, Env, B, E).
|
|
apply(app(plus, N1), N2, _, N) :- integer(N1), integer(N2), N is N1 + N2.
|
|
apply(app(minus, N1), N2, _, N) :- integer(N1), integer(N2), N is N1 - N2.
|
|
|
|
|
|
%% normalize(+E1, +Env, -E2)
|
|
%% Applique toutes les réductions possibles sur E1.
|
|
normalize(X, _, X) :- integer(X); var(X); atom(X).
|
|
%% normalize(X, Env, E) :- atom(X), member((X, E), Env).
|
|
normalize(lambda(X, T, B), Env, lambda(X, Tn, Bn)) :-
|
|
normalize(T, [(X,T)|Env], Tn), normalize(B, [(X,T)|Env], Bn).
|
|
normalize(pi(X, T, B), Env, pi(X, Tn, Bn)) :-
|
|
normalize(T, [(X,T)|Env], Tn), normalize(B, [(X,T)|Env], Bn).
|
|
normalize(forall(X, T, B), Env, forall(X, Tn, Bn)) :-
|
|
normalize(T, [(X,T)|Env], Tn), normalize(B, [(X,T)|Env], Bn).
|
|
normalize(app(E1, E2), Env, En) :-
|
|
normalize(E1, Env, E1n),
|
|
normalize(E2, Env, E2n),
|
|
(apply(E1n, E2n, Env, E) ->
|
|
normalize(E, Env, En);
|
|
En = app(E1n, E2n)).
|
|
|
|
%% infer(+E, +Env, -T)
|
|
%% Infère le type de E dans Env. On essaie d'être permissif, dans le sens
|
|
%% que l'on présume que l'expression est typée correctement.
|
|
infer(X, _, int) :- integer(X).
|
|
infer(X, _, _) :- var(X). %Une expression encore inconnue.
|
|
infer(X, Env, T) :-
|
|
atom(X),
|
|
(member((X, T1), Env) ->
|
|
%% X est déjà dans Env: vérifie que le type est correct.
|
|
T = T1;
|
|
%% X est une variable libre.
|
|
true).
|
|
infer(lambda(X,T,B), Env, pi(Y,T,TB)) :-
|
|
infer(B, [(X,T)|Env], TBx),
|
|
(var(Y) ->
|
|
Y = X, TB = TBx;
|
|
subst(X, Y, Env, TBx, TB)).
|
|
infer(app(E1, E2), Env, Tn) :-
|
|
infer(E1, Env, T1),
|
|
(T1 = pi(X,T2,B); T1 = forall(X,T2,B)),
|
|
infer(E2, Env, T2),
|
|
subst(X, E2, Env, B, T),
|
|
normalize(T, Env, Tn).
|
|
infer(pi(X,T1,T2), Env, type) :-
|
|
infer(T1, Env, type),
|
|
infer(T2, [(X,T1)|Env], type).
|
|
infer(forall(X,T1,T2), Env, type) :-
|
|
infer(T1, Env, type),
|
|
infer(T2, [(X,T1)|Env], type).
|
|
|
|
%% freevars(+E, +Env, -Vs)
|
|
%% Renvoie les variables libres de E. Vs est une liste associative
|
|
%% où chaque élément est de la forme (X,T) où X est une variable et T est
|
|
%% son type.
|
|
freevars(X, _, []) :- integer(X).
|
|
freevars(X, Env, Vs) :-
|
|
atom(X),
|
|
(member((X,_), Env) ->
|
|
%% Variable liée.
|
|
Vs = [];
|
|
%% Variable libre. Type inconnu :-(
|
|
Vs = [(X,_)]).
|
|
%% Les variables non-instanciées peuvent être remplacées par des paramètres
|
|
%% qui seront liés par `closetype' selon le principe de Hindley-Milner.
|
|
freevars(X, _, [(X, _)]) :- var(X), new_atom(X).
|
|
freevars(app(E1, E2), Env, Vs) :-
|
|
freevars(E1, Env, Vs1),
|
|
append(Vs1, Env, Env1),
|
|
freevars(E2, Env1, Vs2),
|
|
append(Vs1, Vs2, Vs).
|
|
freevars(lambda(X, T, B), Env, Vs) :-
|
|
freevars(T, Env, TVs),
|
|
append(TVs, Env, Env1),
|
|
freevars(B, [(X,T)|Env1], BVs),
|
|
append(TVs, BVs, Vs).
|
|
freevars(pi(X, T, B), Env, Vs) :- freevars(lambda(X, T, B), Env, Vs).
|
|
freevars(forall(X, T, B), Env, Vs) :- freevars(lambda(X, T, B), Env, Vs).
|
|
|
|
%% close(+Eo, +To, +Vs, -Ec, -Tc)
|
|
%% Ferme un type ouvert To en liant chaque variable libre (listées dans Vs)
|
|
%% avec `forall'.
|
|
closetype(E, T, [], E, T).
|
|
closetype(Eo, To, [(X,T)|Vs], lambda(X, T, Ec), forall(X, T, Tc)) :-
|
|
closetype(Eo, To, Vs, Ec, Tc).
|
|
|
|
%% elab_type(+Ee, +Te, +Env, -Eg, -Tg)
|
|
%% Ajoute les arguments implicites de E:T.
|
|
generalize(Ee, Te, Env, Eg, Tg) :-
|
|
freevars(Te, Env, Vs),
|
|
append(Vs, Env, EnvX),
|
|
%% Essaie d'instancier les types des paramètres que `generalize' vient
|
|
%% d'ajouter.
|
|
infer(Te, EnvX, type),
|
|
closetype(Ee, Te, Vs, Eg, Tg).
|
|
|
|
%% instantiate(+X, +T, -E)
|
|
%% Utilise la variable X de type T. Le résultat E est X auquel on ajoute
|
|
%% tous les arguments implicites (de valeur inconnue).
|
|
instantiate(X, T, X) :- var(T), !.
|
|
instantiate(X, forall(_, _, T), app(E, _)) :- !, instantiate(X, T, E).
|
|
instantiate(X, _, X).
|
|
|
|
%% elaborate(+E1, +Env, -E2)
|
|
%% Transforme E1 en une expression E2 où le sucre syntaxique a été éliminé
|
|
%% et où les arguments implicites ont été rendus explicites.
|
|
elaborate(X, _, X) :- integer(X); var(X).
|
|
elaborate(X, Env, E) :-
|
|
atom(X),
|
|
(member((X, T), Env) ->
|
|
instantiate(X, T, E);
|
|
%% Si X n'est pas dans l'environnement, c'est une variable libre que
|
|
%% l'on voudra probablement généraliser.
|
|
X = E).
|
|
elaborate(lambda(X, T, B), Env, lambda(X, Te, Be)) :-
|
|
elaborate(T, Env, Te),
|
|
elaborate(B, [(X,Te)|Env], Be).
|
|
elaborate(pi(X, T, B), Env, pi(X, Te, Be)) :-
|
|
elaborate(T, Env, Te),
|
|
elaborate(B, [(X,Te)|Env], Be).
|
|
elaborate(app(E1, E2), Env, app(E1e, E2e)) :-
|
|
elaborate(E1, Env, E1e),
|
|
elaborate(E2, Env, E2e).
|
|
elaborate(let(X, T, E1, E2), Env, app(lambda(X, Tg, E2e), E1g)) :-
|
|
elaborate(E1, Env, E1e),
|
|
elaborate(T, Env, Te),
|
|
infer(E1e, Env, Te),
|
|
generalize(E1e, Te, Env, E1g, Tg),
|
|
elaborate(E2, [(X,Te)|Env], E2e).
|
|
%% Expansion du sucre syntaxique.
|
|
elaborate((T1 -> T2), Env, Ee) :-
|
|
new_atom(X), elaborate(pi(X, T1, T2), Env, Ee).
|
|
elaborate(app(E1, E2, E3, E4), Env, Ee) :-
|
|
elaborate(app(app(E1,E2,E3),E4), Env, Ee).
|
|
elaborate(app(E1, E2, E3), Env, Ee) :- elaborate(app(app(E1,E2),E3), Env, Ee).
|
|
elaborate(lambda(X, B), Env, Ee) :- elaborate(lambda(X, _, B), Env, Ee).
|
|
elaborate(let(X, E1, E2), Env, Ee) :- elaborate(let(X, _, E1, E2), Env, Ee).
|
|
elaborate(fix(F,B,E), Env, Ee) :- elaborate(fix(F,_,B,E), Env, Ee).
|
|
elaborate(fix(F,T,B,E), Env, Ee) :-
|
|
elaborate(let(F,T,app(fix,lambda(F,T,B)),E), Env, Ee).
|
|
|
|
%% elab_bindings(+TS, +Env, -TS).
|
|
%% Applique `elaborate' sur l'environnement de type TS.
|
|
elab_tenv([], _, []).
|
|
elab_tenv([(X,T)|TS], Env, [(X, Tg)|TSe]) :-
|
|
elaborate(T, Env, Te),
|
|
infer(Te, Env, type),
|
|
generalize(_, Te, Env, _, Tg),
|
|
elab_tenv(TS, [(X, Tg)|Env], TSe).
|
|
|
|
|
|
%% elaborate(+E1, -E2)
|
|
%% Comme le `elaborate' ci-dessus, mais avec un environnement par défaut.
|
|
elaborate(SRC, E) :-
|
|
elab_tenv([(int, type),
|
|
(fix, ((t -> t) -> t)),
|
|
%% list: type → int → type
|
|
(list, (type -> int -> type)),
|
|
%% plus: int → int → int
|
|
(plus, (int -> int -> int)),
|
|
%% minus: int → int → int
|
|
(minus, (int -> int -> int)),
|
|
%% nil: list t 0
|
|
(nil, app(app(list,t),0)),
|
|
%% cons: t -> list t n → list t (n + 1)
|
|
(cons, (t -> app(app(list,t),n) ->
|
|
app(app(list,t), app(app(plus,n),1)))) %fixindent
|
|
],
|
|
[(type,type)],
|
|
Env),
|
|
elaborate(SRC, Env, E).
|