ウェブ会議でホワイトボード/PDF に手書き/Debian で使うタブレット

しばらく前(2023年に入ったころ)から、いわゆるウェブ会議を使って、リモートで家庭教師のようなこと(本当は違うのだが少しフェイクを入れるのでここではそういうことにしておく)をやっている。

こちらの環境は Debian で、そもそもプロプライエタリな道具はほぼ存在しないので、いろいろと探し回ることになった。

必要な道具は、まずウェブ会議の仕組みにホワイトボード機能となる。はじめは Jitsi を使っていたのだが、そのホワイトボード機能にバグのようなもの(数十分ほど書いたり消したりしているとハングアップしたようにそれ以上の書いたり消したりができなくなる)が出現して、Whereby を使うようになった。この切り替えはもう3か月ほど前なので、現在(2023年9月末)ではもう解決しているかもしれない。

Whereby は2人(1対1)で使う分には時間無制限なので、ここでの目的では困らない。Whereby ではホワイトボードとして外部サービスの Miro の画面を共有するようになっており、この使い方では Miro にアカウントを作る必要もない。

また、ホワイトボードに PDF を背景画像のように表示させてその上に書き込むように表示させる(家庭教師的に言えば、練習問題のプリントを表示させておいて解説を書き込む)ような使い方は、Jitsi のホワイトボードではできず、バグの有無に関わらず Whereby (Miro) のほうが優れている。

やや話はずれるが、ウェブ会議とは無関係に、既存のPDFに手書きで書き込むようなアプリケーションを探してみたら、Xournal++ というものが見つかった。これはこれでたいへん優れた道具だ。

さて、そのように手書きで書き込む際、マウス(と言っても自分はトラックボールだが)ではなかなか上手く書くことができないので、ペンタブレットを用意することにした。価格が手頃で Linux での実績がありそうな XPPen の Deco Fun XS を購入。お絵描きには小さすぎるかもしれないが、ここでの目的にはちょうどいい。

表面は思いの外ツルツルで、ペンが滑りすぎると感じるので、紙(たとえば便箋)をタブレットの作業エリアに貼り付けた。これで書き味がまさに紙に書いている感じになり、すこぶるよくなった。

XPPen には Linux 用のドライバが用意されている。これがなくても機器を接続するだけで十分使えるのだが、これによってさらに便利に使うことができる。たとえば、タブレットでの作業エリアを画面上の一部領域に設定できたり、ペンのボタンに機能を割り当てたりできるようになる。

ここでは「180度回転」と設定し、タブレットそのものを上下逆さまに置くことにした。このタブレットには作業エリア以外に幅 2cm ほどの部分があり、それを手前に持ってきてちょうどパームレスト(文字を書くので実際には小指の脇か)のように使うことで、より安定して字を書けるようになった。

【以下は、2023年9月末現在の自分の環境(Debian testing)での問題である。】

ところが、ここでは Debian の testing バージョン(安定バージョンではなく、ソフトウェア(パッケージ)が少しずつ新しいものに置き換わっていく)を使用しているため、ある時の Debian の更新以降この XP-Pen 提供のドライバ(この時点で XPPen-pentablet-3.2.3.230215-1.x86_64.deb)が動かなくなってしまった。提供されているドライバは当然にも 対応は Debian 安定版としか謳っていないので文句をいう筋合いではない。

XP-Pen 提供のドライバは実際には /usr/lib/pentablet/pentablet.sh というシェルスクリプト

#!/bin/sh
appname=`basename $0 | sed s,\.sh$,,`
dirname=`dirname $0`
tmp="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname/lib
export LD_LIBRARY_PATH
$dirname/$appname "$@"

を通じて、同じディレクトリの lib/ 以下のライブラリを使いつつ、同じディレクトリの pentablet というバイナリが起動されている。OSバージョンで困らないようにわざわざ同梱されている lib/ 以下のライブラリのどれかが逆に悪さして、このドライバが動かなくなっていた。このシェルスクリプトを飛ばして(LD_LIBRARY_PATHを設定しないようにして)直接 /usr/lib/pentablet/pentablet を起動すると、問題なく使えるようになった。

$ ldd /usr/lib/pentablet/pentablet

	linux-vdso.so.1 (0x00007fff87dc2000)
	libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007f4e0b29d000)
	libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f4e0b15b000)
	libXtst.so.6 => /lib/x86_64-linux-gnu/libXtst.so.6 (0x00007f4e0b153000)
	libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x00007f4e0b13f000)
	libXrandr.so.2 => /lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f4e0b132000)
	libXinerama.so.1 => /lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f4e0b12b000)
	libQt5X11Extras.so.5 => /lib/x86_64-linux-gnu/libQt5X11Extras.so.5 (0x00007f4e0b124000)
	libQt5Widgets.so.5 => /lib/x86_64-linux-gnu/libQt5Widgets.so.5 (0x00007f4e0aa00000)
	libQt5Gui.so.5 => /lib/x86_64-linux-gnu/libQt5Gui.so.5 (0x00007f4e0a200000)
	libQt5Xml.so.5 => /lib/x86_64-linux-gnu/libQt5Xml.so.5 (0x00007f4e0b0e0000)
	libQt5Network.so.5 => /lib/x86_64-linux-gnu/libQt5Network.so.5 (0x00007f4e0a055000)
	libQt5Core.so.5 => /lib/x86_64-linux-gnu/libQt5Core.so.5 (0x00007f4e09a00000)
	libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007f4e0a979000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4e0b0d9000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4e09600000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4e09f76000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4e0b0b5000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4e0941e000)
	libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f4e0a947000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4e0b2d2000)
	libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f4e0a91d000)
	libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007f4e0a908000)
	libXrender.so.1 => /lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f4e0a8fb000)
	libpng16.so.16 => /lib/x86_64-linux-gnu/libpng16.so.16 (0x00007f4e099ca000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f4e099ab000)
	libharfbuzz.so.0 => /lib/x86_64-linux-gnu/libharfbuzz.so.0 (0x00007f4e09884000)
	libmd4c.so.0 => /lib/x86_64-linux-gnu/libmd4c.so.0 (0x00007f4e0a8e9000)
	libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f4e093cb000)
	libdouble-conversion.so.3 => /lib/x86_64-linux-gnu/libdouble-conversion.so.3 (0x00007f4e0986f000)
	libicui18n.so.72 => /lib/x86_64-linux-gnu/libicui18n.so.72 (0x00007f4e09000000)
	libicuuc.so.72 => /lib/x86_64-linux-gnu/libicuuc.so.72 (0x00007f4e08e02000)
	libpcre2-16.so.0 => /lib/x86_64-linux-gnu/libpcre2-16.so.0 (0x00007f4e0933d000)
	libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f4e08d41000)
	libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f4e08bfb000)
	libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f4e08b42000)
	libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007f4e08b0e000)
	libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007f4e09f6a000)
	libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f4e0b0a8000)
	libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f4e08800000)
	libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f4e08a42000)
	libgraphite2.so.3 => /lib/x86_64-linux-gnu/libgraphite2.so.3 (0x00007f4e08a16000)
	libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f4e08724000)
	libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f4e086f7000)
	libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f4e09869000)
	libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f4e0985b000)
	libicudata.so.72 => /lib/x86_64-linux-gnu/libicudata.so.72 (0x00007f4e06800000)
	libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f4e0865c000)
	libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f4e08647000)
	libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f4e0932a000)
	libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007f4e08a09000)
	libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f4e08640000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f4e0862f000)
	libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007f4e08620000)
	libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007f4e085fd000)

ノートパソコンに Debian をインストール

スウちゃん (仮名、4年生) が「ノートパソコンがほしい」と言い出しました。学校でも PC に少し触ることがあるし、家でも親がスマホやタブレットでなく大きな画面でカタカタやっているので興味はあるのでしょう。ほう、では何をやりたいか書き出してごらん、と言うと、「字を打てるようになる」「ゲーム」「メール」「プリント」とのこと。「プリント」って何と聞いてみると、宿題などのために調べ物をしたらそれをプリンターに出したいということでした。

ラップトップ型パソコン

興味を持ったときがチャンスだと思い、早速探してみました。はじめ中古は考えていなかったのですが本人に「中古でもいい?」と聞いてみたらまったく気にしないとのことで、1年落ちで14インチ、メモリ8GB、SSDが240GBという一段上のスペックのものが安い価格で見つかり早速購入。いまどき OS なしのパソコンを探すのは難しいので Windows10 も込みです。状態説明で「タッチパッドにテカリあり」となっていましたが、仮に新品でも使いはじめたらすぐにこのくらいになってしまうだろうという程度で、それに普段使う角度から見るとまったく気になりません。ほかに特に問題はなく、今のところいい買い物だったと思っています。

さて Windows10 が入っていても、私自身が普段使いしておらず面倒を見きれないので、さっそくおさらばすることにします。購入時に聞いたのですが Windows のプロダクトキーはどこかに記載したものは一切ないとのことでしたので、一度 Windows10 で起動して確認し (その方法はネットで探しました)、控えておきます。これで、そのうちどうしても他所と同じ Windows じゃないとと言い出した時には戻せます。

Debian stretch のインストール

現時点での安定版 Debian stretch をインストールしていきます。

まず親機で netinst イメージ (300MB ほど) を USB メモリにコピーします。これをラップトップ機に挿して起動し、あとは画面の指示に従っていくだけです。途中、ハードウェアを解析し必要なものを要求してくるので、それ (firmware-iwlwifi の deb パッケージ) を親機で 別の USB メモリに入れて、ラップトップ機の別の USB の口から与えました。ネットがつながればあとはあっさりインストール完了です。

task-xfce-desktop を選択したので、LibleOffice はじめ一通りのアプリケーションが揃っています。日本語変換は fcitx と mozc (キー設定はMS-IME互換) の組み合わせ。デスクトップのパネルを下に配置することで Windows にかなり似せました。「学校でさわるのとちょっと違うよ」と言い、スウちゃんも今の時点では難なく受け容れています。

スウちゃんの希望 (「ゲーム」は昨年のクリスマスに Nintendo Switch をもらったこともあって却下) に沿うため、thunderbird をインストールしましたが、実際にはまだ使っていません。XMPP (チャット) クライアントの Gajim を入れてやり、同じ家の中から私が話しかけてやります。スピーディだし、絵文字もすぐ選べるから楽しいし、なんとか返答しようとしてキー入力もやります。動機づけには十分です。

印刷のためには、cups のパッケージを一通りと、うちにあるのは Brother のプリンターなので、メーカーのサイトから入手したドライバーをインストール。そうか、そのドライバーは i386 用なので、その前にマルチアーキテクチャ対応にする必要がありました。

久しぶりにクリーンインストールを行いましたが、それにしても Debian のインストールからデスクトップ環境構築までがこんなに楽になっているとは驚きました。

Rhythmbox を DLNA クライアントとして使う

何を今さらというような内容かもしれませんが、ちょっと苦労したのでメモしておきます。

やりたいことは以前書いた「リモートに置いてある音楽ファイルをローカルPCのスピーカーで鳴らす」と同じです。あれから時間が経ってまたまた環境がずいぶん変わってしまいました。現在は宅内のリモートマシンで DLNAサーバー (Debian の minidlna パッケージ) を動かしており、それから手元の PC で何らかの手段で音楽を聴きたいのです。

手元の PC (OS は Debian testing です) にはインターネットラジオを聴くのに Rhythmbox がインストールされていて (Debian パッケージで言うと rhythmbox と rhythmbox-plugins)、これで DLNA を使えればいい訳で、検索してみると Ubuntu 情報ですが、パッケージ grilo-plugins-0.3 と libgrilo-0.3-0 を追加インストールすれば左欄に DLNA サーバーが現れるかその一番下の + でサーバーが見つかるようになる……はずなのですが、ぜんぜん反応しません。

なかなか手がかりがなく困り果てていたのですが、ふと

(rhythmbox:16045): Grilo-WARNING **: [dleyna] grl-dleyna-servers-manager.c:138: Unable to fetch the list of available servers: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name com.intel.dleyna-server was not provided by any .service files

の警告 (エラーではないのであまり気にしていなかった) の中のキーワードから、dleyna-server という Debian のパッケージを追加したら、無事に左欄の「共有」のところに DLNA サーバーが現れました。

結局、必要なのは

  • rhythmbox
  • rhythmbox-plugins

  • grilo-plugins-0.3

のほかに

  • dleyna-server

でした (依存関係でそのほかいくつか)。

しかし、dleyna-server に言及している情報にほとんど行き当たらなかったのはどうしてだろう……。

dvipdfmx の map の置き場所

TeXLive 2016 から 2017 での変化なのか、Debian 固有の問題なのかわからないが、メモ。

LaTeX から PDF を作るのに dvipdfmx を使っている。いまどきは、はじめから pdfLaTeX とか LuaLaTeX を使うのだろうが、もう10年ほどもこの方法で、スクリプトにしてやっているからそのままだ。

つい最近、Debian Testing (Buster) でパッケージを更新したら TeXLive が 2016 から 2017 になったようで、dvipdfmx でフォントを埋め込む際に参照する map ファイルが見つけられず PDF を作れなくなってしまった。map ファイルは /etc/texmf/dvipdfmx/ 以下にある。

調べてみると、/usr/share/texlive/texmf-dist/web2c/texmf.cnf で、以前も今も

TEXMFSYSCONFIG = /etc/texmf

は変わらないが、

TEXMF = {$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFLOCAL,!!$TEXMFDEBIAN,!!$TEXMFDIST}

TEXMF = {$TEXMFAUXTREES$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDEBIAN,!!$TEXMFDIST}

になり、

TEXMFDBS = {!!$TEXMFSYSVAR,!!$TEXMFLOCAL,!!$TEXMFDEBIAN,!!$TEXMFDIST}

TEXMFDBS = {!!$TEXMFLOCAL,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFDEBIAN,!!$TEXMFDIST}

に変更されていた。要するに $TEXMFSYSCONFIG に !! が付き、それが $TEXMFDBS に含められている。

対処としては texmf.cnf の設定を以前と同じようにすればいいのかもしれないが、/etc/texmf/ls-R を (mktexlsr で) 作成すれば、すんなり元のように PDF を作れるようになった。どちらのほうがいいのだろう。

オンラインストレージ hubiC をバックアップに使ってみる

PC のデータのバックアップは、宅内に複数の PC があるので相互にコピーするという安直な方法をとっていました。安直とはいえこれまでに数回、それに救われたことがあります。

しかし複数と言っても、同じ家の中にあります。ふと、もしこの家が火事になったら……と考えてしまいました。まあそのときには PC のデータどころではないでしょうが。

では外のどこに置けばいいのやら。無料のオンラインのストレージサービスを探してみました。そのうち、25GB もあって Linux からも使いやすそうな hubiC を試してみることにしました。

アカウントの作成

メールアドレスが ID になります。そこに紹介コードを入力する欄があります。どこかで紹介コードを入手してここに入力すると、容量 25GB のところ +5GB の計 30GB になります。なおいったんアカウントを作成すると自分の紹介コードができます。これを誰かに紹介して、その誰かがこの紹介コードを使ってアカウントを作成すると、紹介した側も +5GB され、5人分まで加算されて最大 55GB にまでなります。私の紹介コードをここに書いておきます。XWULCF

Debian で使う

まず、ウェブで hubiC にログインし、My accountDevelopersAdd an application とします。適当な名前と URL を入力します。作成できるとその detail に、Client IDSecret Client が表示されます。

次にローカル側(Debian)の準備です。

apt-get install hubicfuse

で、パッケージをインストールします。なお、ここでは Debian Stretch の これを書いている時点でのバージョン hubicfuse 3.0.0 に従って書きます。Jessie のバージョン 1.1.0 だと設定ファイルの書式が異なるようです。

/usr/share/doc/hubicfuse/README.Debian に書かれているとおり、

/usr/share/hubicfuse/hubic_token

を実行します。

client_id, client_secret,redirect_uri を、さきほどのとおり入力します。その後の質問では、括弧の中のとおり rwwrd のように入力します。デフォルトではないので、そのとおりに入力します。

続いて user_loginpassword を入力します。すると、

client_id=.......
client_secret=.......
refresh_token=.......

の3行が表示されます。これをそのまま ~/.hubicfuse というファイルを作ってそこに書き込んで保存します。

マウント

ユーザーを fuse グループに加えておきます。そしてマウントポイント (たとえば ~/mnt/hubic/) を作っておきます。

マウントは

hubicfuse ~/mnt/hubic -o noauto_cache,sync_read

です。あとは通常の操作で、ここにファイルをコピーするなどできます。とは言っても通信速度は(日本からだと)非常に遅いので、この中でいろいろ作業するのは止めたほうがいいでしょう。せいぜい cprm くらいが無難です。安全と謳っていますが、やはり他人任せにするのは心もとないので、データは手元で暗号化してから送ることにしました。

アンマウントは

fusermount -u ~/mnt/hubic

です。

復元手順はふだんから訓練を

通信速度は非常に遅いのですが、万が一の場合の保管場所ということで、そう頻繁にファイルをやりとりすることもないので、これでよしとします。設定が済んでしまえば通常のファイル操作のコマンドでファイルを送ることができるので、自動化するのも楽です。

しかし復元の手順はこれに頼ってはいけません。何しろ火事になって設定ファイルどころか紙に書いたメモも何もかもが失われている、という状況を想定しておかなければなりません。

そもそもデータを hubiC というサービスに置いたということと、そのログイン名とパスワードは頭の中に入れておかなければなりません。それから暗号化ファイルを元に戻す方法もです。

数か月に一度、その訓練をしておくのがいいと思っているところです。

環境変数 CHROMIUM_FLAGS と Chromium のオプション --enable-remote-extensions

自分用メモ。

ほかはどうか知らないが少なくともこれを書いている時点の Debian (Stretch (testing))で、Chromium の拡張機能が無効になってしまった。検索してみると、

バグ報告の最後あたりのコメントにあるように、
export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --enable-remote-extensions"

~/.profile に書き加える。あるいは /usr/share/doc/chromium/NEWS.Debian.gz を参照のこと。

chromium-browser (55.0.2883.75-4) unstable; urgency=medium

  * External extensions are now disabled by default.  Chromium will only load
    extensions that are explicitly specified with the --load-extension command
    line option passed into CHROMIUM_FLAGS.  See the chromium-lwn4chrome
    package for an example of how to do this.
  * You can also use the --enable-remote-extensions command line argument to
    chromium, which will bypass this restriction.

これで拡張機能を有効にできる……はずなのだが、起動時に ~/.profile が読み込まれていない。長いことこれに気がついていなかった。既に不要となった環境変数設定くらいしか書いてなかったからな。

少なくとも Debian の Lightdm を使っている場合、~/.xsessionrc を作ってその中に

. $HOME/.profile

と書いておけば、これが読み込まれる。

『多数決を疑う—社会的選択理論とは何か』を読んだ

多数決を疑う――社会的選択理論とは何か (岩波新書)を読みました。議員選挙などのたびに、多数決よりましな方法があるんじゃなかろうかと漠然と思っていたのですが、それについて追究する学問分野が「社会的選択理論」と呼ばれていることすら知らなかったので、大いに蒙を啓かれることとなりました。

本書の内容は既に公にされている書評(毎日新聞読売新聞など)などにお任せします。検索すればほかにもたくさん見つかります。一方で、きっと本書そのものを読まないままにタイトルだけから「民主主義を否定するのかよ」といった短絡的な批判(?)も見つかります。それほど「民主主義イコール多数決」と思い込んでいる者が多いのでしょう。もちろんそうではありません。意見集約の「方法」についての話なのです。

多数決のもとで有権者は、自分の判断のうちごく一部に過ぎない「どの候補者を一番に支持するか」しか表明できない。(略)だから勝つのは「一番」を最も多く集めた候補者である。(略)

多数決の選挙で勝つためには、どの有権者をも取りこぼさないよう細かく配慮するのは不利というわけだ。とにかく一定数の有権者に一番に支持してもらい、(略)

だがこれは政治家や有権者が悪いのではなく、多数決が悪いのではないだろうか。しかし多数決を採用しているのは人間である。多数決を自明視する固定観念が強い。(本書「はじめに」)

本来であれば社会全体をよくするという政策が出てきてそれが支持されそうなところ、現行の「方法」が多数決であることによって、候補者が勝ちにいくために政策・選挙戦術が歪められ、有権者の行動もまたそれに依存する……。何か本末転倒と思わざるを得ません。

多数決ほど、その機能を疑われないまま社会で使われ、しかも結果が重大な影響を及ぼす仕組みは、他にはなかなかない。とりわ議員や首長や議員を選出する選挙で多数決を使うのは、乱暴というより無謀ではなかろうか。(本書「おわりに」)

多数決の最大の(たぶん唯一の)利点は、「単純でわかりやすい」ということだろうと思います。本書で紹介されるボルダルールやコンドルセ式は集計(開票作業)がどうしても煩雑になります。しかしそれは人間の手作業による場合であって、もし電子投票が実施されるようになればまったく問題はありません。電子投票の問題はたぶん信頼性や投票の秘密の確保とかにあるのでしょうが、いずれその方向にいくでしょう。200年ほども前から提案されている方法に、ようやく技術が追いついてきたと言えます。それに合わせて集約方法も“進化”してもいいのではないでしょうか。

ともかく、多数決よりましな方法が存在します。議員選挙のような簡単には動かしにくい制度よりもっと身近なところ—町内会とかサークルとか学校の生徒会とか—からそういったものが普及していってもらいたいものです。

ボルダルール

さて本書では多数決の代替案がいくつか検討された後、その中でも「ボルダルール」が推されています。その理由として

  1. ペア敗者規準とペア勝者弱規準を満たす
  2. さらに棄権防止性を満たす

が挙げられています。さらに「コンドルセ・ヤングの最尤法は統計学的に定義されるゆえ有権者には理解が難しく、広く受け入れられるとは想像しがたい。であればボルダルールのほうが世に導入しやすいだろう。」と述べています。

しかし、これらについて私は素直に首肯できませんでした。

まず(2)についてです。ここで「棄権防止性」とは、有権者があえて棄権することで結果を自分に有利に変えることができない、という意味で説明され、コンドルセ・ヤングの最尤法ではこれを満たさないとのことです。

ボルダルールでは、候補のすべてに順位を付けて投票しなければなりません。ではたとえば最近の都知事選挙を考えてみます。これだけ候補が多いと、大部分の有権者は、もっとも好ましい候補からせいぜい3人ほどと、この人には絶対なってほしくないという候補の2,3人ほどが頭に浮かぶ程度ではないでしょうか。何がなんでもすべての候補を一列に並べなければならない、とすると有権者への負担はとても大きくなり、そんなことならいっそ棄権してしまおうかという気持ちにもなってしまいそうです。棄権で結果を自分の有利にできないから棄権する動機がないという意味の「棄権防止性」はあるのかもしれませんが、「めんどくささ」からの棄権を多く誘発しそうです。もしすべての候補にではなくて「いくつかだけに順位をつければよい」というルールにすると、それはボルダではない「スコアリングルール」になってしまい、(1)を満たさなくなってしまいます。この「めんどくささ」、つまり有権者の高負担というボルダルールの不利な点をどのように克服できるのか、そこまで本書で説明されていればよかったのにと思いました。

シュルツ方式

本書には出てきませんがコンドルセの一種として「シュルツ方式」というものがあります[1]

Wikipedia のページをざっと読んでみたところ、シュルツ方式の投票は、ボルダルールのように候補に順位を付けますが、

  • 複数の候補者に同じ番号を付けてもよい
  • 連続しない番号をつけてもよい。番号の絶対値は重要ではなく、順序のみに着目する
  • いくつかの候補に順位を付けなくてもよい。その場合、順位付けしていない候補を最下位(順位付けしていない候補どうしは同列)とみなす

というものです。コンドルセ式のためペア勝者規準をも満たすようですし、また全部の候補を順位付けせずに部分だけでもよい、とありますから、上に挙げた私のボルダルールに対する疑念も克服されているようです。簡単な比較の日本語記事が『「多数決」以上に民意を反映できる選挙方法とはどのようなものなのか?』にありました(本書の出版より前の記事です)。

Debian Project採決にこの方式を採用しているということを、実は以前から知っていました。しかしこれが多数決などとどのような関係にあるか、考えたことはなかったのです。今回、『多数決を疑う』を読み、あらためて見てみました。英語ですが The Debian Voting System は、Debian での方法に限らず一般的なコンドルセやシュルツの説明としてわかりやすいです。

そこにあるように、Debian 方式は

  • 選択肢に「更に議論する」を追加する
  • デフォルトはこの「更に議論する」とする

という拡張がなされています。一般の投票なら「他に選択肢がない」や「どちらともいえない」などを読み替えることができるでしょう。つまりデフォルト選択肢より上の順位にすれば「好ましい」、下の順位は「好ましくない。嫌だ」という意思表示になります。これはたいへん合理的なルールだと思えます。

この拡張の優れた点は、ただの賛否を問う採決でも(選択肢が「賛成」「反対」の2つしかなければボルダルールも何もただの多数決になってしまう)、選択肢が「賛成」「反対」「更に議論する」の3つになり、コンドルセ式などを適用できることです。もっともこれを「迅速に決定できない」という欠点だとみなすこともできますが、私は、拙速よりははるかにましだと考えます。

多数決を疑う――社会的選択理論とは何か (岩波新書)……と、実は本書を読んだのは数か月前なのですが、何しろ専門でも何でもないので、調べたり考えたりしながらこの辺まで書くのにうんと手間取ってしまいました。このままではいつまでたっても書き上がらないので、ひどく中途半端ですがもうここでこの記事を公開してしまうことにします。

ついでに、私の抱いているもうひとつの疑問も書いておきます。

私の住む市の今年春の市議会議員選挙では、立候補者数は定数をわずかに超えるだけでした。つまり30人ほどが当選し、ほんの3,4人しか落選しません。最適の候補をたったひとつ選ぶ場合にはコンドルセ式やボルダルールが使えそうですが、このような場合にも適用できるのでしょうか。本書からだけではよくわかりませんでした。たとえば「投票方式はこれで決まり?」で言及されている方法などは有用そうなのですが、それと他の方式との比較などが自力ではよくわからない……。

様々なケースにも適用できるベストな方法はどうやらなさそうだ、という感じはうすうすしているのですが、それでも本書で言うように「コンドルセ式よりもボルダルールが優れている」とは思えませんでした。さらにもっと別の方式も同じ土俵に上げて、上述した疑問にも私のような素人にもわかりやすく答えてくれる、続編に相当するものが現れないかなと思っているところです。

  1. WikiPediaの解説はとても参考になりますが日本語版の「シュルツ方式」は翻訳が変なところも多い(2015年9月現在。そう思っているなら直せよと言われそうですが、時間があれば少しづつそうしていきたいと思います。しかし私のような素人よりもっと専門知識のある人たちにやってほしい……)ので、それを参照しながら英語版 Schulze method を見たほうがよさそうです。