272 lines
17 KiB
HTML
272 lines
17 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<!-- This manual documents Guile version 3.0.10.
|
||
|
|
||
|
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
|
||
|
Inc.
|
||
|
|
||
|
Copyright (C) 2021 Maxime Devos
|
||
|
|
||
|
Copyright (C) 2024 Tomas Volf
|
||
|
|
||
|
|
||
|
Permission is granted to copy, distribute and/or modify this document
|
||
|
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||
|
any later version published by the Free Software Foundation; with no
|
||
|
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
|
||
|
copy of the license is included in the section entitled "GNU Free
|
||
|
Documentation License." -->
|
||
|
<title>SRFI-1 Set Operations (Guile Reference Manual)</title>
|
||
|
|
||
|
<meta name="description" content="SRFI-1 Set Operations (Guile Reference Manual)">
|
||
|
<meta name="keywords" content="SRFI-1 Set Operations (Guile Reference Manual)">
|
||
|
<meta name="resource-type" content="document">
|
||
|
<meta name="distribution" content="global">
|
||
|
<meta name="Generator" content=".texi2any-real">
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
|
||
|
<link href="index.html" rel="start" title="Top">
|
||
|
<link href="Concept-Index.html" rel="index" title="Concept Index">
|
||
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
||
|
<link href="SRFI_002d1.html" rel="up" title="SRFI-1">
|
||
|
<link href="SRFI_002d1-Association-Lists.html" rel="prev" title="SRFI-1 Association Lists">
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
|
||
|
div.example {margin-left: 3.2em}
|
||
|
span:hover a.copiable-link {visibility: visible}
|
||
|
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
|
||
|
-->
|
||
|
</style>
|
||
|
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
|
||
|
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body lang="en">
|
||
|
<div class="subsubsection-level-extent" id="SRFI_002d1-Set-Operations">
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="SRFI_002d1-Association-Lists.html" accesskey="p" rel="prev">Association Lists</a>, Up: <a href="SRFI_002d1.html" accesskey="u" rel="up">SRFI-1 - List library</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
<hr>
|
||
|
<h4 class="subsubsection" id="Set-Operations-on-Lists"><span>7.5.3.10 Set Operations on Lists<a class="copiable-link" href="#Set-Operations-on-Lists"> ¶</a></span></h4>
|
||
|
<a class="index-entry-id" id="index-list-set-operation"></a>
|
||
|
|
||
|
<p>Lists can be used to represent sets of objects. The procedures in
|
||
|
this section operate on such lists as sets.
|
||
|
</p>
|
||
|
<p>Note that lists are not an efficient way to implement large sets. The
|
||
|
procedures here typically take time <em class="math"><var class="var">m</var>x<var class="var">n</var></em> when
|
||
|
operating on <var class="var">m</var> and <var class="var">n</var> element lists. Other data structures
|
||
|
like trees, bitsets (see <a class="pxref" href="Bit-Vectors.html">Bit Vectors</a>) or hash tables (see <a class="pxref" href="Hash-Tables.html">Hash Tables</a>) are faster.
|
||
|
</p>
|
||
|
<p>All these procedures take an equality predicate as the first argument.
|
||
|
This predicate is used for testing the objects in the list sets for
|
||
|
sameness. This predicate must be consistent with <code class="code">eq?</code>
|
||
|
(see <a class="pxref" href="Equality.html">Equality</a>) in the sense that if two list elements are
|
||
|
<code class="code">eq?</code> then they must also be equal under the predicate. This
|
||
|
simply means a given object must be equal to itself.
|
||
|
</p>
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_003c_003d"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset<=</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_003c_003d"> ¶</a></span></dt>
|
||
|
<dd><p>Return <code class="code">#t</code> if each list is a subset of the one following it.
|
||
|
I.e., <var class="var">list1</var> is a subset of <var class="var">list2</var>, <var class="var">list2</var> is a subset of
|
||
|
<var class="var">list3</var>, etc., for as many lists as given. If only one list or no
|
||
|
lists are given, the return value is <code class="code">#t</code>.
|
||
|
</p>
|
||
|
<p>A list <var class="var">x</var> is a subset of <var class="var">y</var> if each element of <var class="var">x</var> is
|
||
|
equal to some element in <var class="var">y</var>. Elements are compared using the
|
||
|
given <var class="var">=</var> procedure, called as <code class="code">(<var class="var">=</var> xelem yelem)</code>.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset<= eq?) ⇒ #t
|
||
|
(lset<= eqv? '(1 2 3) '(1)) ⇒ #f
|
||
|
(lset<= eqv? '(1 3 2) '(4 3 1 2)) ⇒ #t
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_003d"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset=</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_003d"> ¶</a></span></dt>
|
||
|
<dd><p>Return <code class="code">#t</code> if all argument lists are set-equal. <var class="var">list1</var> is
|
||
|
compared to <var class="var">list2</var>, <var class="var">list2</var> to <var class="var">list3</var>, etc., for as many
|
||
|
lists as given. If only one list or no lists are given, the return
|
||
|
value is <code class="code">#t</code>.
|
||
|
</p>
|
||
|
<p>Two lists <var class="var">x</var> and <var class="var">y</var> are set-equal if each element of <var class="var">x</var>
|
||
|
is equal to some element of <var class="var">y</var> and conversely each element of
|
||
|
<var class="var">y</var> is equal to some element of <var class="var">x</var>. The order of the
|
||
|
elements in the lists doesn’t matter. Element equality is determined
|
||
|
with the given <var class="var">=</var> procedure, called as <code class="code">(<var class="var">=</var> xelem
|
||
|
yelem)</code>, but exactly which calls are made is unspecified.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset= eq?) ⇒ #t
|
||
|
(lset= eqv? '(1 2 3) '(3 2 1)) ⇒ #t
|
||
|
(lset= string-ci=? '("a" "A" "b") '("B" "b" "a")) ⇒ #t
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002dadjoin"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-adjoin</strong> <var class="def-var-arguments">= list elem …</var><a class="copiable-link" href="#index-lset_002dadjoin"> ¶</a></span></dt>
|
||
|
<dd><p>Add to <var class="var">list</var> any of the given <var class="var">elem</var>s not already in the list.
|
||
|
<var class="var">elem</var>s are <code class="code">cons</code>ed onto the start of <var class="var">list</var> (so the
|
||
|
return value shares a common tail with <var class="var">list</var>), but the order that
|
||
|
the <var class="var">elem</var>s are added is unspecified.
|
||
|
</p>
|
||
|
<p>The given <var class="var">=</var> procedure is used for comparing elements, called as
|
||
|
<code class="code">(<var class="var">=</var> listelem elem)</code>, i.e., the second argument is one of
|
||
|
the given <var class="var">elem</var> parameters.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset-adjoin eqv? '(1 2 3) 4 1 5) ⇒ (5 4 1 2 3)
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002dunion"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-union</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_002dunion"> ¶</a></span></dt>
|
||
|
<dt class="deffnx def-cmd-deffn" id="index-lset_002dunion_0021"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-union!</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_002dunion_0021"> ¶</a></span></dt>
|
||
|
<dd><p>Return the union of the argument list sets. The result is built by
|
||
|
taking the union of <var class="var">list1</var> and <var class="var">list2</var>, then the union of
|
||
|
that with <var class="var">list3</var>, etc., for as many lists as given. For one list
|
||
|
argument that list itself is the result, for no list arguments the
|
||
|
result is the empty list.
|
||
|
</p>
|
||
|
<p>The union of two lists <var class="var">x</var> and <var class="var">y</var> is formed as follows. If
|
||
|
<var class="var">x</var> is empty then the result is <var class="var">y</var>. Otherwise start with
|
||
|
<var class="var">x</var> as the result and consider each <var class="var">y</var> element (from first to
|
||
|
last). A <var class="var">y</var> element not equal to something already in the result
|
||
|
is <code class="code">cons</code>ed onto the result.
|
||
|
</p>
|
||
|
<p>The given <var class="var">=</var> procedure is used for comparing elements, called as
|
||
|
<code class="code">(<var class="var">=</var> relem yelem)</code>. The first argument is from the result
|
||
|
accumulated so far, and the second is from the list being union-ed in.
|
||
|
But exactly which calls are made is otherwise unspecified.
|
||
|
</p>
|
||
|
<p>Notice that duplicate elements in <var class="var">list1</var> (or the first non-empty
|
||
|
list) are preserved, but that repeated elements in subsequent lists
|
||
|
are only added once.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset-union eqv?) ⇒ ()
|
||
|
(lset-union eqv? '(1 2 3)) ⇒ (1 2 3)
|
||
|
(lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) ⇒ (5 4 1 2 1 3)
|
||
|
</pre></div>
|
||
|
|
||
|
<p><code class="code">lset-union</code> doesn’t change the given lists but the result may
|
||
|
share a tail with the first non-empty list. <code class="code">lset-union!</code> can
|
||
|
modify all of the given lists to form the result.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002dintersection"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-intersection</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002dintersection"> ¶</a></span></dt>
|
||
|
<dt class="deffnx def-cmd-deffn" id="index-lset_002dintersection_0021"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-intersection!</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002dintersection_0021"> ¶</a></span></dt>
|
||
|
<dd><p>Return the intersection of <var class="var">list1</var> with the other argument lists,
|
||
|
meaning those elements of <var class="var">list1</var> which are also in all of
|
||
|
<var class="var">list2</var> etc. For one list argument, just that list is returned.
|
||
|
</p>
|
||
|
<p>The test for an element of <var class="var">list1</var> to be in the return is simply
|
||
|
that it’s equal to some element in each of <var class="var">list2</var> etc. Notice
|
||
|
this means an element appearing twice in <var class="var">list1</var> but only once in
|
||
|
each of <var class="var">list2</var> etc will go into the return twice. The return has
|
||
|
its elements in the same order as they were in <var class="var">list1</var>.
|
||
|
</p>
|
||
|
<p>The given <var class="var">=</var> procedure is used for comparing elements, called as
|
||
|
<code class="code">(<var class="var">=</var> elem1 elemN)</code>. The first argument is from <var class="var">list1</var>
|
||
|
and the second is from one of the subsequent lists. But exactly which
|
||
|
calls are made and in what order is unspecified.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset-intersection eqv? '(x y)) ⇒ (x y)
|
||
|
(lset-intersection eqv? '(1 2 3) '(4 3 2)) ⇒ (2 3)
|
||
|
(lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) ⇒ (2 2)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The return from <code class="code">lset-intersection</code> may share a tail with
|
||
|
<var class="var">list1</var>. <code class="code">lset-intersection!</code> may modify <var class="var">list1</var> to form
|
||
|
its result.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002ddifference"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-difference</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002ddifference"> ¶</a></span></dt>
|
||
|
<dt class="deffnx def-cmd-deffn" id="index-lset_002ddifference_0021"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-difference!</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002ddifference_0021"> ¶</a></span></dt>
|
||
|
<dd><p>Return <var class="var">list1</var> with any elements in <var class="var">list2</var>, <var class="var">list3</var> etc
|
||
|
removed (ie. subtracted). For one list argument, just that list is
|
||
|
returned.
|
||
|
</p>
|
||
|
<p>The given <var class="var">=</var> procedure is used for comparing elements, called as
|
||
|
<code class="code">(<var class="var">=</var> elem1 elemN)</code>. The first argument is from <var class="var">list1</var>
|
||
|
and the second from one of the subsequent lists. But exactly which
|
||
|
calls are made and in what order is unspecified.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset-difference eqv? '(x y)) ⇒ (x y)
|
||
|
(lset-difference eqv? '(1 2 3) '(3 1)) ⇒ (2)
|
||
|
(lset-difference eqv? '(1 2 3) '(3) '(2)) ⇒ (1)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The return from <code class="code">lset-difference</code> may share a tail with
|
||
|
<var class="var">list1</var>. <code class="code">lset-difference!</code> may modify <var class="var">list1</var> to form
|
||
|
its result.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002ddiff_002bintersection"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-diff+intersection</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002ddiff_002bintersection"> ¶</a></span></dt>
|
||
|
<dt class="deffnx def-cmd-deffn" id="index-lset_002ddiff_002bintersection_0021"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-diff+intersection!</strong> <var class="def-var-arguments">= list1 list2 …</var><a class="copiable-link" href="#index-lset_002ddiff_002bintersection_0021"> ¶</a></span></dt>
|
||
|
<dd><p>Return two values (see <a class="pxref" href="Multiple-Values.html">Returning and Accepting Multiple Values</a>), the difference and
|
||
|
intersection of the argument lists as per <code class="code">lset-difference</code> and
|
||
|
<code class="code">lset-intersection</code> above.
|
||
|
</p>
|
||
|
<p>For two list arguments this partitions <var class="var">list1</var> into those elements
|
||
|
of <var class="var">list1</var> which are in <var class="var">list2</var> and not in <var class="var">list2</var>. (But
|
||
|
for more than two arguments there can be elements of <var class="var">list1</var> which
|
||
|
are neither part of the difference nor the intersection.)
|
||
|
</p>
|
||
|
<p>One of the return values from <code class="code">lset-diff+intersection</code> may share
|
||
|
a tail with <var class="var">list1</var>. <code class="code">lset-diff+intersection!</code> may modify
|
||
|
<var class="var">list1</var> to form its results.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
<dl class="first-deffn">
|
||
|
<dt class="deffn" id="index-lset_002dxor"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-xor</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_002dxor"> ¶</a></span></dt>
|
||
|
<dt class="deffnx def-cmd-deffn" id="index-lset_002dxor_0021"><span class="category-def">Scheme Procedure: </span><span><strong class="def-name">lset-xor!</strong> <var class="def-var-arguments">= list …</var><a class="copiable-link" href="#index-lset_002dxor_0021"> ¶</a></span></dt>
|
||
|
<dd><p>Return an XOR of the argument lists. For two lists this means those
|
||
|
elements which are in exactly one of the lists. For more than two
|
||
|
lists it means those elements which appear in an odd number of the
|
||
|
lists.
|
||
|
</p>
|
||
|
<p>To be precise, the XOR of two lists <var class="var">x</var> and <var class="var">y</var> is formed by
|
||
|
taking those elements of <var class="var">x</var> not equal to any element of <var class="var">y</var>,
|
||
|
plus those elements of <var class="var">y</var> not equal to any element of <var class="var">x</var>.
|
||
|
Equality is determined with the given <var class="var">=</var> procedure, called as
|
||
|
<code class="code">(<var class="var">=</var> e1 e2)</code>. One argument is from <var class="var">x</var> and the other
|
||
|
from <var class="var">y</var>, but which way around is unspecified. Exactly which
|
||
|
calls are made is also unspecified, as is the order of the elements in
|
||
|
the result.
|
||
|
</p>
|
||
|
<div class="example">
|
||
|
<pre class="example-preformatted">(lset-xor eqv? '(x y)) ⇒ (x y)
|
||
|
(lset-xor eqv? '(1 2 3) '(4 3 2)) ⇒ (4 1)
|
||
|
</pre></div>
|
||
|
|
||
|
<p>The return from <code class="code">lset-xor</code> may share a tail with one of the list
|
||
|
arguments. <code class="code">lset-xor!</code> may modify <var class="var">list1</var> to form its
|
||
|
result.
|
||
|
</p></dd></dl>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
<hr>
|
||
|
<div class="nav-panel">
|
||
|
<p>
|
||
|
Previous: <a href="SRFI_002d1-Association-Lists.html">Association Lists</a>, Up: <a href="SRFI_002d1.html">SRFI-1 - List library</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|