2016-12-26

誤り:paizaの問題はC++17でも成り立つ

この記事は間違っていた。

この変更では、インクリメント演算子の副作用のコミット順序はまだ規定されていない。

paizaが以下のような質問を出している。

問題は、int i = 0 ;であるとき、以下の式を評価した結果が1になるのはどれかという問題だ。
  1. i++ + ++i
  2. ++i + ++i
  3. i++ + i++
  4. ++i + i++

C言語では、この式を評価した結果は未定義である。

C++14までは、この式を評価した結果は未定義である。

C++17では、サブ式の評価順序が固定されたことにより、この式は以下のように評価されることが規格上保証されている。

C++17でも未だに未定義。§1.10 p18に書かれている。

  1. 2
  2. 3
  3. 1
  4. 2

参考:

[PDF] P0145R3: Refining Expression Evaluation Order for Idiomatic C++

P0400R0: Wording for Order of Evaluation of Function Arguments

現在、Clang 4.0 headがP0145R3とP0400R0を正しく実装している。GCC 7 headはP0145R3の実装を謳っているが現時点ではバグのため、2番目の式の評価が4になるようだ。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2016-12-09

freeeの保有する特許5503795について読んで解釈を試みたがやはり新規性も技術的価値もわからないしゴミだったのでfreeeのエンジニアは早くfleeするべき

freeeが特許侵害でマネーフォワードに訴訟を起こしたそうだ。freeeのプレスリリースでもその事実を記載している。

特許権侵害訴訟の提起について | プレスリリース | freee株式会社

これによると、マネーフォワードが侵害したとfreeeが主張している特許は、特許第5503795号だそうだ。他の特許については触れていないのでこの特許を読んでみることにする。

特許 第5503795号 会計処理装置、会計処理方法及び会計処理プログラム - astamuse

この特許は本当にゴミなのだが、私の解釈した限りで、この特許を使った技術的な実装とは以下のようなものだ。ここで、この特許が主張している文脈やアイディアは無視して、単なる根本的な実装のみを書いている。

ユーザーの利用している金融機関やクレジットカードの取引の履歴データ(何をどこからいくらで買った、売ったという取引情報)をWeb上からスクレイピングする。

会計処理では、取引情報は、勘定科目という様々な名目に仕訳しなければならない。勘定科目とは、例えば費用の項目では、仕入とか接待交際費とか消耗品費とか賃借料といったものである。スクレイピングした取引履歴情報には、勘定科目はない。勘定科目というのはその文脈に依存する。例えば、鉛筆を購入したとして、その鉛筆を自社の社員が業務のために使うのであれば名目は消耗品費だ。鉛筆を更に第三者に販売するのであれば名目は仕入だ。

勘定科目は人間がその文脈に基づいて分類しなければならないのだが、ある程度の推測はできる。例えば、鉛筆の購入費用は、水道光熱費とか保険料にはまずならない。大方は消耗品費か仕入だろうし、大抵の場合は消耗品費だろう。したがって取引履歴情報から「鉛筆」というキーワードを抽出して、キーワードと勘定科目の対応テーブルを参照して、自動的に勘定科目の仕訳を行うことができる。

自動で仕分けた上で、人間に仕訳結果を見せて、間違いは修正させる。

とまあ、基本的にはこのような実装だ。

ちょっとまてよ、そんな分類作業は会計や簿記といった概念が発明されて以来行われている極めて一般的な既知既存の作業ではないか。キーワードで勘定科目を推定することに新規性などあるのか。

この特許は、極めてバカバカしい、人をけむにまくような、ポストモダンもかくやと思われるような言葉遣いをして、このような人間が何千年も行ってきた作業を再発明している。

まず、請求項1の冒頭を読んでみよう。

請求項1

クラウドコンピューティングによる会計処理を行うための会計処理装置であって、

「クラウドコンピューティング」とは一体何を意味する言葉であろうか。一般的に考えればAWSとかAzureのようなプラットフォームのことを言うのであろうか。クラウドだろうが非クラウドだろうが本質的には大差ないし、第一肝心の処理を実装するソフトウェアのみかけの実行環境は古典的なコンピューターと全く変わらない。クラウドは既存のソフトウェア資産を使えるように大変な努力をしているからだ。

気を取り直して、続きを読んでいこう。

ユーザーにクラウドコンピューティングを提供するウェブサーバを備え、

おや、「クラウドコンピューティング」とはユーザーに提供するものなのか。ということはAWSとかAzureなどではないということになる。freeeは自ら「クラウド会計ソフト」と名乗っている。すると、エンジニアがインフラとして使う意味のクラウドコンピューティングではなく、ユーザー側ではなくサーバー側で処理を行うことを「クラウドコンピューティング」と称しているのだろうか。こちらの意味であれば、例えばGMailはクラウド電子メールソフトであるし、Google Docsはクラウド表計算ソフトということもできる。

この特許の前文を検索しても、「クラウドコンピューティング」なる用語の定義が出てこない。ただし、

本発明はウェブ明細データを利用する点で、現時点では、中小企業及び個人事業主のうち、その恩恵を受けることができる割合が限られている。すなわち、我が国の企業におけるクラウドコンピューティングの利用率は、非特許文献1に記載されているとおり、9.1%に過ぎない、つまり大部分においてウェブ上のリソースが活用されていないのである。本発明は、中小企業及び個人事業主に初めて焦点を当てた上で、かつ、今後のクラウドコンピューティングの利用率向上を見越してなされたものであり、そこに大きな先進性がある。

この非特許文献1というのは、総務省、平成23年通信利用動向調査(企業編)、31頁のことで、以下から入手できる(ただしHTTPなので改変されていない保証がない。)

http://www.soumu.go.jp/johotsusintokei/statistics/pdf/HR201100_002.pdf

これによれば、クラウドコンピューティングの定義はしていないが、どうやら処理の一部をサーバー側で行い、ユーザー側のクライアントにWebブラウザーを使うソフトウェアのことを意味しているようだ。

しかし、「Web上のリソースが活用されていない」という表現は謎である。まるですでに持っている資産を使わずに放置しているような書きようだが、サービスを使う契約すら結んでいないのに、活用していないとは一体なんだろうか。例えば東京には流しのタクシーが多数走っているが、タクシーにほとんど乗らない東京人は、「公道上のタクシーリソースを活用していない」と言えるのだろうか。

そして、先進性というのも疑問だ。というのも、GMailは10年以上前に公開されているし、それ以前にもWeb上でメールを管理、送信できるようなWebサイトは、クラウドという言葉の登場以前にも存在していた。企業が使いたいかどうかということに先進性があるのだろうか。より使いやすいUI、管理しやすい機能、セキュリティなどは、別にいまに限った話ではない。

なぜ筆者が「クラウドコンピューティング」なる用語の定義にこんなに細かく考察しているかというと、この特許では、「クラウドコンピューティング」なる用語を多用しているからだ。特許の文章中に13回使われている。例えば、

ウェブサーバが提供するクラウドコンピューティングによる

クラウドコンピューティングによる会計処理を行うための会計処理装置

ユーザーにクラウドコンピューティングを提供するウェブサーバ

Webブラウザーをクライアントとして使いサーバー側の処理に依存するソフトウェアが、Webブラウザーではないソフトウェアクライアントと比べて技術的に何か先進性があるようには思われない。特許のクラウドコンピューティングをクライアントサーバー型サービスに変えても別に何の違いも内容に思われる。

クラウドコンピューティングという用語の使い方だけで謎であるし新規性のかけらも感じられない。

特許では、さも当たり前の人間が何千年もやっている作業が、まるで先例なく画期的な思いつきによって発明されたかのように書かれている。

例えば、キーワードには表記ゆれがある。ANAはエー・エヌ・エーと書かれるかもしれないし、エーエヌエーと書かれるかもしれない。このようなひらがな、カタカナ、漢字、アルファベット、ハイフンの有無、マイナス、長音記号などの表記ゆれを補正して同じキーワードとして扱うようにする処理が、あたかも画期的な思いつきで実施したところ効果があったかのように書かれている。

また、「モロゾフ JR大阪三越伊勢丹店」のようにキーワードが複数ある場合、JR大阪三越伊勢丹店のJRというキーワードで勘定科目を推定すると旅費交通費だが、モロゾフという洋菓子店で推定すると、贈答品を購入したので接待費だと推定できる。このように複数のキーワードがある場合、キーワードの種類によって優先度を設けることで、正しい判定ができる。この優先度として、品名は取引先より優先させた方が推定の制度が上がることが画期的なひらめきにより発見されたなどとしている。そんな複数のキーワードに優先順位をつけることは人間が何千年も行ってきたことであるし、コンピューターの発明以後即座に行われただろうに、どういう新規性があるのだろうか。

ちなみに、この特許は一度却下されているのだが、この優先順位という請求項を付け加えることで認められている。

この特許は、会計処理は発生主義の原則に基づいて「デイリーベース」(1日単位でという意味か?)で行われているが、個人や中小企業などの場合、期日までに会計処理を終わらせればよく、自動的に仕訳をした上で、ユーザーにWebブラウザー上で候補を表示して修正させる方法で、一括して仕訳を行うので、新規性があるとしている。

これもよくわからない話だ。というのも、人間が行う金の動きなのだから、その日のうちに申請し忘れて期日ギリギリに会計処理を行うことなど大企業であってもよくあるだろうし、コンピューターが今のように高性能になる前は、バッチ処理といってデータを一括で一気に処理していたものだ。すると、バッチ処理をしていた頃のコンピューターシステムで、キーワードに対応した分類を行うもので、更に会計処理をする先例が存在すれば、この特許は無効になる。そのような先例は探せばあるのではないかと思われるし、会計処理に限定したところで何か技術的に変わるとも思えない。

この特許は、とにかく人間が文字と数学を発明して以来、数千年も行ってきた会計処理という既存の作業をコンピューターでやったという他なく、しかもそのコンピューターというのが、クラウドコンピューティングとかWebサーバーとかWebブラウザーとか極めて限定的な範囲になっている。いくら範囲を狭めたところで、技術的に何か新規性のある発明には思えない。

さて、こんなゴミ特許は一体誰が発明したのか。特許に記載の情報によれば、佐々木大輔、横路隆、平栗遵宜が発明者になっている。

freeeのWebサイトの会社概要によれば、

会社概要 | freee株式会社

佐々木大輔は創業者で代表取締役。「形式的で非効率なことは大嫌い」とあるが、こんなゴミ特許を形式的で非効率的なゴミ特許を取得した上で、競合他社を極めて短い交渉期間でまるで妨害するかのように訴訟を起こす形式主義と非効率性は持ち合わせているようだ。

横路隆はCTOで共同創業者。「テクノロジーでスモールビジネスのありかたを再定義していきます」とあるが、技術ではなく特許で競合他社を妨害するビジネスを定義中のようだ。定義といえば、クラウドコンピューティングなる謎の用語も定義していただきたい。

平栗遵宜は開発本部長。「ユーザーに価値を届けるために必要なのは技術力と気合」とあるが、技術力ではなくゴミ特許で競合他社を妨害することで他の価値を抹消した上で唯一の価値を独占して届けるようだ。まさに気合が必要とされる。

創業者で代表取締役、共同創業者でCTO、開発本部長といった、役職キーワードから推定して会社の運営や技術の方向性の最終的な判断をする役割の人間が技術で勝負せず、くだらないゴミ特許を恥ずかしげもなく申請して同業他社に特許訴訟を起こすとは、freeeの技術的な先行きが危ぶまれる。

freeeのエンジニアは早くfleeするべきではないか。

2016-12-08

freeeのゴミのような特許の新規性が全く理解できない

freeeが特許侵害でマネーフォワードを提訴したというニュースが流れている。

freeeがマネーフォワードを提訴、勘定科目の自動仕訳特許侵害で | TechCrunch Japan

肝心の特許は、以下のものらしい。

特許 第5503795号 会計処理装置、会計処理方法及び会計処理プログラム - astamuse

読んでみたが、何の新規性もあるようには読めない。やたらとクラウドコンピューティングなる言葉が出てくるが、この特許でAWSとかAzureとかGoogle Apps Engineのようないわゆるクラウドかそうでない従来のサーバーかで何か違いがあるとは思えないし、その他のことも、人間が有史以前からやってきた分類作業であるようにしか読めない。数千年も存在する既存の概念をコンピューターで行うというだけのゴミ特許が乱立しているが、どうやらそのコンピューターを更に細分化してクラウドコンピューティングとかウェブサーバーとかのバズワードを追加しただけで、範囲をいくら狭めようと分類は分類でしかない。

特許制度は消え去るべきだ。

そして、歴史的に、このような特許ゴロ訴訟をしだす企業というのは4パターンある。

  • 何も具体的な特許技術を利用した現物を提供していないが、ゴミのような特許権だけ保有していて、わずかでも抵触している可能性のある企業団体個人に対して特許利用料を支払え、さもなくば訴訟だと迫るもの
  • 大量のゴミ特許を保有している大企業が小遣い稼ぎに、お前はうちの膨大な特許プールのどれかを侵害している可能性があるので特許使用料を支払え、さもなくば訴訟だと迫るもの
  • 競合相手に対し自由市場による競争をしたくないため存在を妨害するためにゴミ特許を振りかざして利益が出ないほど法外な利用料を要求して訴訟を行うもの
  • 時代についていけない死に体で破産寸前の企業が昔取ったゴミ特許を振りかざして最後の小遣い稼ぎを試みるもの

この特許は本当に新規性のかけらもない。

2016-12-07

江添ボドゲ会@12月24日

12月24日に私の自宅でボードゲームを遊ぶ会を開催することにした。参加方法と会場の場所は以下の通り。

江添ボドゲ回@12月24日 - connpass

参考書に昔の技法を書くべきか:C++17のコンパイル時分岐

今、C++17のライブラリの参考書を書いているのだが、C++14時代の、今は現役だが、もうすぐ古代の技術になる技法を紹介すべきかどうか迷っている。

問題はコンパイル時分岐だ。たとえば、イテレーターがランダムアクセスイテレーターかどうかで、最適な処理が異なるアルゴリズムがあったとする。以下のように書けばいいだろうか。

template < typename Iterator >
void algorithm( Iterator first, Iterator last )
{
    if ( std::is_same<
            std::random_access_iterator_tag,
            typename std::iterator_traits<Iterator>::iterator_category
        >{}
    )
    {
        // ランダムアクセスイテレーターに特化した高速なアルゴリズム
        first + 1 ; // ランダムアクセスイテレーターの処理の例
    }
    else {
    // Forward Iteratorにも対応できるアルゴリズム
    }
}

残念ながら、このコードにランダムアクセスイテレーター以外を渡すとコンパイルエラーになる。その理由は、イテレーターと整数をoperaotr +に渡しているからだ。これはランダムアクセスイテレーターしか提供していない操作だ。

コンパイルエラーを防ぐには、あるテンプレートコードが条件次第で実体化される措置が必要だ。つまり、コンパイル時分岐が必要になる。

C++14でコンパイル時分岐を実現する方法はふたつある。関数テンプレートのオーバーロードを使う方法と、テンプレートの特殊化(部分的特殊化)だ。

関数テンプレートのオーバーロードを使うには、以下のようにiterator_tagでオーバーロード解決を行う。


template < typename Iterator >
void algorithm_impl( Iterator first, Iterator last,
    std::random_access_iterator_tag )
{
// ランダムアクセスイテレーターを必要とする処理
}

template < typename Iterator >
void algorithm_impl( Iterator first, Iterator last,
    std::bidirectional_iterator_tag )
{
// 双方向イテレーターを必要とする処理
}

template < typename Iterator >
void algorithm( Iterator first, Iterator last )
{

    algorithm_impl( first, last,
        typename std::iterator_traits<Iterator>::iterator_category{}
    ) ;
}

テンプレートの特殊化は特にひねりはない。

template < typename T >
struct algorithm_impl
{
template < typename Iterator >
static void process( Iterator first, Iterator last )
{
// 前方イテレーター以上が必要な処理
}

} ;

template  <>
struct algorithm_impl< std::random_access_iterator_tag >
{
template < typename Iterator >
static void process( Iterator first, Iterator last )
{
    first + 1 ;
}

}

template < typename Iterator >
void algorithm( Iterator first, Iterator last )
{

    algorithm_impl<
        typename std::iterator_traits<Iterator>::iterator_category
    >::process( first, last ) ;
}

このようにコンパイル時分岐は実現できるのだが、C++17ではconstexpr ifが入ったことでこのような技法は古臭いハックに成り下がってしまった。

template < typename Iterator >
void algorithm( Iterator first, Iterator last )
{
    using iterator_category = typename std::iterator_tratis<Iterator>::iterator_category ;

    // ランダムアクセスイテレーターの場合の処理
    if constexpr ( std::is_same< iterator_category, std::random_access_iterator_tag >{} )
    {
        first + 1 ;
    }
    // 前方イテレーター以上
    else
    {
    }
}

constexpr ifがあれば、昔の泥臭いコンパイル時分岐ハックはいらなくなる。とすれば、参考書にわざわざ昔のハックを書く必要はない。

とはいえ、それはC++17が普及してからの話だ。C++17が制定されるのにまだ1年かかり、GCCやClangの規格準拠のC++コンパイラーの安定版がリリースされるまでに数年かかり、普及には更に時間がかかる。

とはいえ、歴史を振り返れば、かつてのenumハックがstatic constな整数型のデータメンバーになり、今ではstatic constexprなデータメンバーになっているのを考えると、わざわざ昔のハックを載せる必要はないように思える。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2016-12-01

AWSのアクセスキーをハニートークンとして使うアイディア

Early Warning Detectors Using AWS Access Keys as Honeytokens

この発想はなかった。

AWSのアクセスキーはハニートークンとして使える。

ハニートークンとは、普段使用しないものが使用されたことを検知して、意図しない利用を検知するトリックである。例えば、通常ならば使われないメールアドレスをパスワードとともに、自分しかアクセスできないストレージに格納しておく。その状態で、もしメールサーバーにログインされた場合は、自分しかアクセスできないはずのストレージに他人がアクセスして、マヌケにもメールアドレスとパスワードをストレージ上に保存しているのを発見して、利用を試みたということになる。つまり、侵入を検知できる。

AWSのアクセスキーは、ハニートークンに使うことができる。AWSに権限を持たないユーザーを追加して、そのユーザーでアクセスキーを発行する。アクセスキーの使用を検知してログをとったりアラートを飛ばしたりするために、AWSのCloudTrail/CloudWatchを設定する。あとはこのアクセスキーを自分しかアクセスできないはずの秘密の場所にばらまいておけばいい。たとえば、

  • サーバーのストレージ、特に ツールが慣習的に使う~/.aws/credentialsなど
  • 自分のローカルのコンピューターのストレージ
  • アプリケーションとかsystemdの設定ファイルの中
  • GitHubのプライベートレポジトリ

その後、アクセスキーが使われた場合、自分以外の誰かが自分以外には本来アクセスできないはずのストレージにアクセスしたということだ。

この方法の素晴らしいことには、AWSのインスタンスは立ち上げないため、金がかからないということだ。アクセスキーは無料でいくらでも発行できる。