% Demo how to declare in prover9 that the terms in a list are distinct. % David A. Wheeler % Released to the public domain. % Usage: % prover9 -f *.in > *.out % Use prolog naming format (initial uppercase is variable): set(prolog_style_variables). formulas(assumptions). % Define distinct(List): Each item in List is not equal to all the others. distinct([First, Second : Rest]) -> ( (First != Second) & distinct([First : Rest]) & distinct([Second : Rest])). % Simple demonstration of how to use distinct(). This declares that each % term a..g is not equal to all the other terms: distinct([a,b,c,d,e,f,g]). end_of_list. % Simple demonstration, to show that it works: formulas(goals). b != f. end_of_list. % Note: distinct() works because eventually each recursion will reach a % "bottom" that asserts distinct([one_item]). Since the precondition requires % at least 2 list elements, a one-element list terminates each recursion. % The definition of distinct() is only useful when passed a list with % at least 2 elements (since otherwise being 'distinct' is meaningless). % Systems with more Prolog-like syntaxes would use "|" instead of ":". % If Prolog naming format is NOT used, distinct() could be defined as: % distinct([x,y:z]) -> ( (x != y) & distinct([x:z]) & distinct([y:z])). % Later versions of mace4 have an undocumented list(distinct), e.g.: % list(distinct). % Objects in each list are distinct. % [a,b,c,d,e,f,g]. % end_of_list. % This does NOT work with prover9. % This implementation of distinct(List) is also a useful way to show % how to implement some other (more complicated) constructs in prover9.