Did you know ... | Search Documentation: |
Packs (add-ons) for SWI-Prolog |
Title: | Refactoring Tools for SWI-Prolog |
---|---|
Rating: | |
Latest version: | 1.0.0 |
SHA1 sum: | 33587ac2d680a60882388d12de7926df3830f80c |
Author: | Edison Mera http://www.edisonm.com/ |
Maintainer: | Edison Mera http://www.edisonm.com/ |
Packager: | Edison Mera http://www.edisonm.com/ |
Home page: | https://github.com/edisonm/refactor |
Download URL: | https://github.com/edisonm/refactor.git |
Requires: | xlibrary |
xtools |
Version | SHA1 | #Downloads | URL |
---|---|---|---|
0.0.2 | 09e98519abb88ea6e7c2fad12d1d0ad8ea429310 | 1 | https://github.com/edisonm/refactor.git |
1027056ab13cc0607bd7fab3d2c2cbc0dccda1c5 | 1 | https://github.com/edisonm/refactor.git | |
10b1ebef4c7f9b0f75be7642eda37bf2a2aebebe | 1 | https://github.com/edisonm/refactor.git | |
1602d14c75dde0e0acce455abab822bfdaffac56 | 1 | https://github.com/edisonm/refactor.git | |
1996dbbf67c733075f48804185d47ae406ee928a | 1 | https://github.com/edisonm/refactor.git | |
1f726c65a9a063b5c10ee16a3bd1e266974d60f9 | 2 | https://github.com/edisonm/refactor.git | |
3b58ad0a453bf120feb422ba3dac9abb2157b3fd | 2 | https://github.com/edisonm/refactor.git | |
551e11896a3fe2a7e3224177277857a0535923de | 1 | https://github.com/edisonm/refactor.git | |
5f911e50cf41e91bebe626c6517fbac3a68a415c | 1 | https://github.com/edisonm/refactor.git | |
6c05b6318444cf3fee84589df066c37ca003a0d1 | 1 | https://github.com/edisonm/refactor.git | |
8518f54474a4625b99fc0134ef6d29325c37274d | 2 | https://github.com/edisonm/refactor.git | |
85b986ef461a32fa774e60a9ef2297d07f7ea2a5 | 1 | https://github.com/edisonm/refactor.git | |
bd607e78e481d0ce9d2257160a43f19c9ebcaa66 | 2 | https://github.com/edisonm/refactor.git | |
bde8495daf43c84d09cc66f7cb8586ca37c02c45 | 1 | https://github.com/edisonm/refactor.git | |
c21416045a74237456c04b0ef1aae0016883555f | 1 | https://github.com/edisonm/refactor.git | |
ccca58945bcd812f47b262a22070d85cd11e5295 | 1 | https://github.com/edisonm/refactor.git | |
f16019ef26161ee5f436828537da22ad9f6532c2 | 1 | https://github.com/edisonm/refactor.git | |
fa2eabcab73d36ca4f8ac7d6f2a3dd3bdeacb8c2 | 2 | https://github.com/edisonm/refactor.git | |
0.0.3 | 0901b90fb535479063a20bfac8f81d9a27718f49 | 1 | https://github.com/edisonm/refactor.git |
0f5ecd9e7f509edddc64b9f5d95134ee00ae3a39 | 1 | https://github.com/edisonm/refactor.git | |
11612f5c6cf828d6c3ecb420af2dcdf3d362d313 | 2 | https://github.com/edisonm/refactor.git | |
190b15c6e507a7490d31462766097247db74325d | 2 | https://github.com/edisonm/refactor.git | |
1bd67cb5a0d26b26b68170cb97fb664bb8a25fcf | 1 | https://github.com/edisonm/refactor.git | |
22ff1a0873dcb785e76fbc5aee596644cec19e41 | 1 | https://github.com/edisonm/refactor.git | |
23932efe2e653286d2415875fc727df24ecb999e | 2 | https://github.com/edisonm/refactor.git | |
241026a8d037805ab70b6642608ea31870e8d375 | 1 | https://github.com/edisonm/refactor.git | |
3577663e93a7d10e0c2288530679532c284aeeb3 | 1 | https://github.com/edisonm/refactor.git | |
3cdfb68976d43f688a0ea762978a72073788581e | 5 | https://github.com/edisonm/refactor.git | |
3cebd38fc067da950cab0e4aadbb23d6906f46f2 | 2 | https://github.com/edisonm/refactor.git | |
3d84e38abc2c8cdd11beaf2eb31fb44b7b8de7c1 | 2 | https://github.com/edisonm/refactor.git | |
497e78359ed51b778634af03228673a1b6e3672c | 1 | https://github.com/edisonm/refactor.git | |
4f7da0583c48b1771b8cdf9bbd29235da866acaf | 1 | https://github.com/edisonm/refactor.git | |
503f3c8e06c3bdae4f4f2a189794b2d57400bdad | 2 | https://github.com/edisonm/refactor.git | |
510cc3bf16e89a6eb9e726b1313457b998d24871 | 1 | https://github.com/edisonm/refactor.git | |
57cf29f8814a24f3d220648a2530cdbceb2517a4 | 1 | https://github.com/edisonm/refactor.git | |
645a41b25f465c0d0aed6d95a42f0fb0767d7d5b | 1 | https://github.com/edisonm/refactor.git | |
68a85e2af568f0b8f08ccacebb5fd840d1ac7239 | 2 | https://github.com/edisonm/refactor.git | |
738e77ee49caa95f07842af8cece5498775cb581 | 2 | https://github.com/edisonm/refactor.git | |
761367eeca5989cd999c1873f615b00d978288cf | 1 | https://github.com/edisonm/refactor.git | |
7d86afc213d248323e371da782f86349fa7f88b6 | 1 | https://github.com/edisonm/refactor.git | |
83072f8bb852309416af5dd075974b9297fe9787 | 1 | https://github.com/edisonm/refactor.git | |
842753913135bb71f7c031c80d7c3e551f5b1834 | 1 | https://github.com/edisonm/refactor.git | |
84463925008750981bb500b16c932f13110c70c5 | 1 | https://github.com/edisonm/refactor.git | |
88749a139418040df5e80a4c1382241302941bf8 | 8 | https://github.com/edisonm/refactor.git | |
947f0056e3e2c850d62199b2dc5e8a1c2a3e68b5 | 2 | https://github.com/edisonm/refactor.git | |
948989572b301c7e1be6718fdaf21034d56ca6ef | 2 | https://github.com/edisonm/refactor.git | |
96aba7014ed9f4ebf537aba674195dcda88db7fb | 1 | https://github.com/edisonm/refactor.git | |
9a77544199ad72bcf687b90f789475aa8c435ca2 | 1 | https://github.com/edisonm/refactor.git | |
9e5b0b08aad212004402f6647ff5d9594c696619 | 4 | https://github.com/edisonm/refactor.git | |
a5f9332dbc4b992784c34484096a8a9ce2be0393 | 2 | https://github.com/edisonm/refactor.git | |
a7340776739f3d90c8e05729fc47004a946adafa | 1 | https://github.com/edisonm/refactor.git | |
acc9bdc44889d86eaff3a074007bd19595d285f0 | 1 | https://github.com/edisonm/refactor.git | |
bfb61314a67fe2c93b15e6335420f827bbdf23bc | 1 | https://github.com/edisonm/refactor.git | |
c4ef4ecfe28851de2f20eddcd1e43f5f26b9ba7b | 3 | https://github.com/edisonm/refactor.git | |
c657ee9976c009ad02b316ae22ce99498411e7cc | 1 | https://github.com/edisonm/refactor.git | |
cf5b94ba03b2ef37caf83d22a96f91a2c0701779 | 1 | https://github.com/edisonm/refactor.git | |
d4ac01c62e0a3070dfd05eba0915ce6b1bf10b3e | 1 | https://github.com/edisonm/refactor.git | |
ddc154f96073de53c82b949d52ab40a940979bbd | 2 | https://github.com/edisonm/refactor.git | |
ec2c0d7b12297558a54ce7ee0592760433fce1f8 | 1 | https://github.com/edisonm/refactor.git | |
efa2e98ba98a160961ae47104d2cf54db004447e | 2 | https://github.com/edisonm/refactor.git | |
f224c99dad7bb870014f6d0f2bea681659e89229 | 2 | https://github.com/edisonm/refactor.git | |
f4fa0f0d53c0e8f5f1b69d17772af7a53992434d | 1 | https://github.com/edisonm/refactor.git | |
fc807f48b637e659d628bfe37da9e83ac7dbdabe | 1 | https://github.com/edisonm/refactor.git | |
ffae25b6abe091fc9a8df54aa4a0af6b80a002cf | 1 | https://github.com/edisonm/refactor.git | |
1.0.0 | 33587ac2d680a60882388d12de7926df3830f80c | 5 | https://github.com/edisonm/refactor.git |
Refactoring Tools for SWI-Prolog
To install the refactoring tools, just follow the next sequence of commands in your SWI-Prolog shell:
$ swipl ?- pack_install('https://github.com/edisonm/refactor.git'). true.
There are two groups of predicates, one to rewrite the source code, and other
one to manage such changes. The basic predicate that performs the
transformation is replace/5, implemented in library(ref_replace)
. The
predicates to manage such transformations are implemented in library(ref_shell)
,
which provides methods to keep track of the modifications and to make the
changes to the files permanent. To make things easy, you can download all the
required libraries by loading library(refactor)
.
This is more clear with an example. First load the library:
?- [library(refactor)]. true.
In the folder tests/ you can see useful examples about its usage, let's pick from
there the module repl_conj.pl, and let's replace the term a(B)
by aa(B)
:
?- cd(tests). true. ?- replace_term(a(B), aa(B), [file(repl_conj)]). % 3 changes of 3 attempts % Saved changes in index 1 true.
In this example we use the options argument to say that we want to apply the changes to the file repl_conj.pl, but we can use other ways to define the scope of the chages, like the directory (dir option), list of directories (dirs option) and list of files (files option) to mention a few.
The last information message shows in the first line the number of changes performed out of the number of attempts, and in the second one, the index the changes belong to, which is used in some predicates like rdiff/1 and will be explained later. The number of changes will not match with the number of attempts if the expansion was rejected by the expander, for instance, suppose that we want to perform such change in all places except in those where the clause doesn't have body:
?- replace_term(a(B), aa(B), (Sentence = (_ :- _)), [file(repl_conj), sentence(Sentence)]). % 2 changes of 3 attempts % Saved changes in index 1 true.
To review the changes, use rshow:
?- rshow. diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -1,12 +1,12 @@ :- module(repl_conj, [repl_conj/0]). repl_conj :- - a(C), + aa(C), b(b), c(C), d(d). repl_conj :- - a(a), + aa(a), b(b). a(_). true.
If we don't agree with the changes, execute rreset to undo them, otherwise execute rcommit:
?- rcommit. true.
Continuous calls to refactor predicates can be stacked so you could implement
complex scenarios via small ones. For instance, suppose you also want to change
b(C)
by bb(C)
and c(DD)
by cc(DD)
, then first we execute rreset just to be sure no
changes are pending folowed with the calls to perform the changes:
?- rreset. true. ?- replace_term(a(B), aa(B), [file(repl_conj), sentence(Sentence)]). % 3 changes of 3 attempts % Saved changes in index 1 true. ?- replace_term(b(B), bb(B), [file(repl_conj), sentence(Sentence)]). % 3 changes of 3 attempts % Saved changes in index 2 true. ?- replace_term(c(D), cc(D), [file(repl_conj), sentence(Sentence)]). % 2 changes of 2 attempts % Saved changes in index 3 true. ?- rshow. diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -1,15 +1,15 @@ :- module(repl_conj, [repl_conj/0]). repl_conj :- - a(C), - b(b), - c(C), + aa(C), + bb(b), + cc(C), d(d). repl_conj :- - a(a), - b(b). + aa(a), + bb(b). -a(_). -b(_). -c(_). +aa(_). +bb(_). +cc(_). d(_). true.
As soon as the refactorings become more complex or touch more files, it results difficult to use only rshow. In such cases it's more convenient to save the differencies in a diff file:
?- rsave('changes.diff'). true.
Be aware that if before to call rcommit we modify some files by hand, those changes will be overwritten, therefore the refactoring needs to be applied again. That can be performed easily with the command rrewind:
?- rrewind. % 3 changes of 3 attempts % 3 changes of 3 attempts % 2 changes of 2 attempts true.
You can check each one of the changes with rdiff(Index)
, where Index is a number
to refer to the given change. If Index is uninstantiated, rdiff/1 will show all
the changes via backtracking. For instance:
?- rdiff(X). diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -3,7 +3,7 @@ repl_conj :- aa(C), bb(b), - c(C), + cc(C), d(d). repl_conj :- aa(a), @@ -11,5 +11,5 @@ aa(_). bb(_). -c(_). +cc(_). d(_). X = 3 ; diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -2,14 +2,14 @@ repl_conj :- aa(C), - b(b), - c(C), + bb(b), + cc(C), d(d). repl_conj :- aa(a), - b(b). + bb(b). aa(_). -b(_). -c(_). +bb(_). +cc(_). d(_). X = 2 ; diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -1,15 +1,15 @@ :- module(repl_conj, [repl_conj/0]). repl_conj :- - a(C), - b(b), - c(C), + aa(C), + bb(b), + cc(C), d(d). repl_conj :- - a(a), - b(b). + aa(a), + bb(b). -a(_). -b(_). -c(_). +aa(_). +bb(_). +cc(_). d(_). X = 1.
Or for a specific index:
?- rdiff(2). diff -ruN repl_conj.pl - --- repl_conj.pl (source) +++ repl_conj.pl (target) @@ -2,14 +2,14 @@ repl_conj :- aa(C), - b(b), - c(C), + bb(b), + cc(C), d(d). repl_conj :- aa(a), - b(b). + bb(b). aa(_). -b(_). -c(_). +bb(_). +cc(_). d(_). true.
Some refactoring scenarios that result from the composition of multiple changes are implemented in the library ref_scenarios.pl.
Other complex scenarios are implemented in its own modules, as follows:
% TBD: Document the next steps to make move_preds.pl work, but note that this % example runs under plsteroids, not rtchecks: ?- [loadall]. ?- [library(calls_to)]. ?- collect_calls_to([dir('.')], _). ?- [library(module_links)]. ?- [library(move_preds)]. ?- update_depends_of. % rreset, % move_preds([put_mark/1], stchecks/prolog/check_unused, xtools/prolog/mark_preds, []), % rsave('ps.diff').
Please, before to read it, be aware that this paper is provided here for historical reasons, since the implementation and interface have changed quite a lot.
Edison Mera, Jan Wielemaker: Porting and refactoring Prolog programs: the PROSYN case study. TPLP 13(4-5-Online-Supplement) (2013)
http://www.swi-prolog.org/download/publications/prosyn.pdf
Pack contains 173 files holding a total of 321K bytes.
Great stuff! I managed to rewrite Ciao lpdoc documentation into PlDoc quite easily. It would be great to have some more documentation though!
Had to manually install the
assertions
pack.