Re: Testing that you have at least one solution from each clause of a predicate
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 03/28/2014 11:04 PM, Kaitain Jones wrote: > I'm trying to find an elegant way to add or remove separate clauses to/from > a test predicate. So I might require that a data structure I have passes > all three filter clauses I have. Obviously there can be no dependencies > between these clauses, i.e. a solution found in clause 2 can have no > dependencies on a specific solution found in clause 1. Essentially I'm > looking for something along these lines: > > filter( List ) :- > member( a, List ). > > filter( List ) :- > member( 1, List ). > > filter( List ) :- > length( List, L ), > L > 2. > > So I want to test if any given List passes all three of my filter tests. > [a,1,x] would pass, but [a,a,a] would not, and [a,1] would not. There might This is of course a bit odd. Multiple clauses form a disjunction and you try to use them as a conjunction. I understand you want this because you want to change the set of conditions dynamically, no? What about doing this? test_all_filters(X) :- forall(clause(filter(X), Body), call(Body)). The disadvantage is that you decompile and recompile each body. If these are simple, that won't matter too much, but if they are really complicated, it might start to matter. If you have an identifier for each filter clause, you can also do test_all_filters(X) :- forall(filter_id(Id), filter(Id, X)). The potentially nice thing is that you can enable/disable filters by assert/retract of the simple fact filter_id/1. The above seems so obvious that I fear I missed something ... Cheers --- Jan > be multiple solutions for one or all clauses, but I need to know that every > clause had at least one solution. Is there an elegant way to do this? Best > thing I could think up was this: > > test_all_filters( X ) :- > findall( Index, filter( Index,X ), SolutionsList ), > findall( IClause, nth_clause( filter( _, _ ), IClause,_), AllClauses ), > > list_to_set( SolutionsList, Solutions ), > length( Solutions, SolutionsLength ), > length( AllClauses, AllClausesLength ), > SolutionsLength >= AllClausesLength. > > And then require an extra identifying arg on each clause: > > filter( 1, X ) :- > X > 2; X > 0. > > filter( 2, X ) :- > X > 5. > > filter( 3, X ) :- > 0 is X mod 2. > > This seems to work: test_all_filters/1 will succeed with 6, 8, 10 etc. It > will fail with 4: it gets three solutions in total, but two of them are > from the first filter and one is from the third, with no solution from the > second, so it only has a set of two solution indices but a clauses list of > size three. > > Is there a better way? > -------------- next part -------------- > HTML attachment scrubbed and removed > _______________________________________________ > SWI-Prolog mailing list > [email protected] > https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog >