Did you know ... Search Documentation:
Packs (add-ons) for SWI-Prolog

Package "refactor"

Title:Refactoring Tools for SWI-Prolog
Rating:
(1/1)
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

Reviews

Write a review or add a rating.

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.

Tuesday 13 July 2021, Jan Wielemaker

Details by download location

VersionSHA1#DownloadsURL
0.0.209e98519abb88ea6e7c2fad12d1d0ad8ea4293101https://github.com/edisonm/refactor.git
1027056ab13cc0607bd7fab3d2c2cbc0dccda1c51https://github.com/edisonm/refactor.git
10b1ebef4c7f9b0f75be7642eda37bf2a2aebebe1https://github.com/edisonm/refactor.git
1602d14c75dde0e0acce455abab822bfdaffac561https://github.com/edisonm/refactor.git
1996dbbf67c733075f48804185d47ae406ee928a1https://github.com/edisonm/refactor.git
1f726c65a9a063b5c10ee16a3bd1e266974d60f92https://github.com/edisonm/refactor.git
3b58ad0a453bf120feb422ba3dac9abb2157b3fd2https://github.com/edisonm/refactor.git
551e11896a3fe2a7e3224177277857a0535923de1https://github.com/edisonm/refactor.git
5f911e50cf41e91bebe626c6517fbac3a68a415c1https://github.com/edisonm/refactor.git
6c05b6318444cf3fee84589df066c37ca003a0d11https://github.com/edisonm/refactor.git
8518f54474a4625b99fc0134ef6d29325c37274d2https://github.com/edisonm/refactor.git
85b986ef461a32fa774e60a9ef2297d07f7ea2a51https://github.com/edisonm/refactor.git
bd607e78e481d0ce9d2257160a43f19c9ebcaa662https://github.com/edisonm/refactor.git
bde8495daf43c84d09cc66f7cb8586ca37c02c451https://github.com/edisonm/refactor.git
c21416045a74237456c04b0ef1aae0016883555f1https://github.com/edisonm/refactor.git
ccca58945bcd812f47b262a22070d85cd11e52951https://github.com/edisonm/refactor.git
f16019ef26161ee5f436828537da22ad9f6532c21https://github.com/edisonm/refactor.git
fa2eabcab73d36ca4f8ac7d6f2a3dd3bdeacb8c22https://github.com/edisonm/refactor.git
0.0.30901b90fb535479063a20bfac8f81d9a27718f491https://github.com/edisonm/refactor.git
0f5ecd9e7f509edddc64b9f5d95134ee00ae3a391https://github.com/edisonm/refactor.git
11612f5c6cf828d6c3ecb420af2dcdf3d362d3132https://github.com/edisonm/refactor.git
190b15c6e507a7490d31462766097247db74325d2https://github.com/edisonm/refactor.git
1bd67cb5a0d26b26b68170cb97fb664bb8a25fcf1https://github.com/edisonm/refactor.git
22ff1a0873dcb785e76fbc5aee596644cec19e411https://github.com/edisonm/refactor.git
23932efe2e653286d2415875fc727df24ecb999e2https://github.com/edisonm/refactor.git
241026a8d037805ab70b6642608ea31870e8d3751https://github.com/edisonm/refactor.git
3577663e93a7d10e0c2288530679532c284aeeb31https://github.com/edisonm/refactor.git
3cdfb68976d43f688a0ea762978a72073788581e5https://github.com/edisonm/refactor.git
3cebd38fc067da950cab0e4aadbb23d6906f46f22https://github.com/edisonm/refactor.git
3d84e38abc2c8cdd11beaf2eb31fb44b7b8de7c12https://github.com/edisonm/refactor.git
497e78359ed51b778634af03228673a1b6e3672c1https://github.com/edisonm/refactor.git
4f7da0583c48b1771b8cdf9bbd29235da866acaf1https://github.com/edisonm/refactor.git
503f3c8e06c3bdae4f4f2a189794b2d57400bdad2https://github.com/edisonm/refactor.git
510cc3bf16e89a6eb9e726b1313457b998d248711https://github.com/edisonm/refactor.git
57cf29f8814a24f3d220648a2530cdbceb2517a41https://github.com/edisonm/refactor.git
645a41b25f465c0d0aed6d95a42f0fb0767d7d5b1https://github.com/edisonm/refactor.git
68a85e2af568f0b8f08ccacebb5fd840d1ac72392https://github.com/edisonm/refactor.git
738e77ee49caa95f07842af8cece5498775cb5812https://github.com/edisonm/refactor.git
761367eeca5989cd999c1873f615b00d978288cf1https://github.com/edisonm/refactor.git
7d86afc213d248323e371da782f86349fa7f88b61https://github.com/edisonm/refactor.git
83072f8bb852309416af5dd075974b9297fe97871https://github.com/edisonm/refactor.git
842753913135bb71f7c031c80d7c3e551f5b18341https://github.com/edisonm/refactor.git
84463925008750981bb500b16c932f13110c70c51https://github.com/edisonm/refactor.git
88749a139418040df5e80a4c1382241302941bf88https://github.com/edisonm/refactor.git
947f0056e3e2c850d62199b2dc5e8a1c2a3e68b52https://github.com/edisonm/refactor.git
948989572b301c7e1be6718fdaf21034d56ca6ef2https://github.com/edisonm/refactor.git
96aba7014ed9f4ebf537aba674195dcda88db7fb1https://github.com/edisonm/refactor.git
9a77544199ad72bcf687b90f789475aa8c435ca21https://github.com/edisonm/refactor.git
9e5b0b08aad212004402f6647ff5d9594c6966194https://github.com/edisonm/refactor.git
a5f9332dbc4b992784c34484096a8a9ce2be03932https://github.com/edisonm/refactor.git
a7340776739f3d90c8e05729fc47004a946adafa1https://github.com/edisonm/refactor.git
acc9bdc44889d86eaff3a074007bd19595d285f01https://github.com/edisonm/refactor.git
bfb61314a67fe2c93b15e6335420f827bbdf23bc1https://github.com/edisonm/refactor.git
c4ef4ecfe28851de2f20eddcd1e43f5f26b9ba7b3https://github.com/edisonm/refactor.git
c657ee9976c009ad02b316ae22ce99498411e7cc1https://github.com/edisonm/refactor.git
cf5b94ba03b2ef37caf83d22a96f91a2c07017791https://github.com/edisonm/refactor.git
d4ac01c62e0a3070dfd05eba0915ce6b1bf10b3e1https://github.com/edisonm/refactor.git
ddc154f96073de53c82b949d52ab40a940979bbd2https://github.com/edisonm/refactor.git
ec2c0d7b12297558a54ce7ee0592760433fce1f81https://github.com/edisonm/refactor.git
efa2e98ba98a160961ae47104d2cf54db004447e2https://github.com/edisonm/refactor.git
f224c99dad7bb870014f6d0f2bea681659e892292https://github.com/edisonm/refactor.git
f4fa0f0d53c0e8f5f1b69d17772af7a53992434d1https://github.com/edisonm/refactor.git
fc807f48b637e659d628bfe37da9e83ac7dbdabe1https://github.com/edisonm/refactor.git
ffae25b6abe091fc9a8df54aa4a0af6b80a002cf1https://github.com/edisonm/refactor.git
1.0.033587ac2d680a60882388d12de7926df3830f80c5https://github.com/edisonm/refactor.git

refactor

Refactoring Tools for SWI-Prolog

Installation

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.

How it works

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).

Example of Usage

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:

  • deref_reexport.pl helps to replace reexport declarations by use_module declarations
  • file_to_module.pl convert included files to modules
  • move_preds.pl helps to move predicates from one file to another
    
    % 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').
    

Papers

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

Contents of pack "refactor"

Pack contains 173 files holding a total of 321K bytes.