:- module(clauses, [list2conj/2, conj2list/2, clauselength/2]). %%! @{ /** @file clauses.yap @defgroup clauses Clause Manipulation @ingroup library This library supports a number of useful utilities that come up over and over again when manipulating Prolog programs. This will include operations and conversion to other structures. @author Vitor Santos Costa */ /** conj2list( +Conj, -List) is det Generate a list from a conjunction of literals. It is often easier to apply operations on lists than on clauses */ conj2list( Conj, List ) :- conj2list( Conj, List, [] ). conj2list( C ) --> { var(C) }, !, [C]. conj2list( true ) --> !. conj2list( (C1, C2) ) --> !, conj2list( C1 ), conj2list( C2 ). conj2list( C ) --> [C]. /** conj2list( +List, -Conj) is det Generate a conjunction from a list of literals. Notice that this relies on indexing within the list to avoid creating choice-points. */ list2conj([], true). list2conj([Last], Last). list2conj([Head,Next|Tail], (Head,Goals)) :- list2conj([Next|Tail], Goals). /** clauselength( +Clause, -Length) is det Count the number of literals in a clause (head counts as one). Notice that this is 1+length(conj2list), as we ignore disjunctions. */ clauselength( (_Head :- Conj), Length ) :- clauselength( Conj, Length, 1 ). clauselength( C, I1, I ) :- { var(C) }, !, I1 is I+1. clauselength( (C1, C2), I2, I ) :- !, clauselength( C1, I1, I ), clauselength( C2, I2, I1 ). clauselength( _C, I1, I ) :- I1 is I+1.