1
0
Fork 0
cl-sites/guile.html_node/SRFI_002d1-Set-Operations.html

272 lines
17 KiB
HTML
Raw Normal View History

2024-12-17 12:49:28 +01:00
<!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> &nbsp; [<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"> &para;</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&lt;=</strong> <var class="def-var-arguments">= list &hellip;</var><a class="copiable-link" href="#index-lset_003c_003d"> &para;</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&lt;= eq?) &rArr; #t
(lset&lt;= eqv? '(1 2 3) '(1)) &rArr; #f
(lset&lt;= eqv? '(1 3 2) '(4 3 1 2)) &rArr; #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 &hellip;</var><a class="copiable-link" href="#index-lset_003d"> &para;</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&rsquo;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?) &rArr; #t
(lset= eqv? '(1 2 3) '(3 2 1)) &rArr; #t
(lset= string-ci=? '(&quot;a&quot; &quot;A&quot; &quot;b&quot;) '(&quot;B&quot; &quot;b&quot; &quot;a&quot;)) &rArr; #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 &hellip;</var><a class="copiable-link" href="#index-lset_002dadjoin"> &para;</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) &rArr; (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 &hellip;</var><a class="copiable-link" href="#index-lset_002dunion"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002dunion_0021"> &para;</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?) &rArr; ()
(lset-union eqv? '(1 2 3)) &rArr; (1 2 3)
(lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) &rArr; (5 4 1 2 1 3)
</pre></div>
<p><code class="code">lset-union</code> doesn&rsquo;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 &hellip;</var><a class="copiable-link" href="#index-lset_002dintersection"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002dintersection_0021"> &para;</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&rsquo;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)) &rArr; (x y)
(lset-intersection eqv? '(1 2 3) '(4 3 2)) &rArr; (2 3)
(lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) &rArr; (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 &hellip;</var><a class="copiable-link" href="#index-lset_002ddifference"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002ddifference_0021"> &para;</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)) &rArr; (x y)
(lset-difference eqv? '(1 2 3) '(3 1)) &rArr; (2)
(lset-difference eqv? '(1 2 3) '(3) '(2)) &rArr; (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 &hellip;</var><a class="copiable-link" href="#index-lset_002ddiff_002bintersection"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002ddiff_002bintersection_0021"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002dxor"> &para;</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 &hellip;</var><a class="copiable-link" href="#index-lset_002dxor_0021"> &para;</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)) &rArr; (x y)
(lset-xor eqv? '(1 2 3) '(4 3 2)) &rArr; (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> &nbsp; [<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>