<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>자습 on Nyan101 Blog</title><link>https://nyan101.github.io/category/%EC%9E%90%EC%8A%B5/</link><description>Recent content in 자습 on Nyan101 Blog</description><generator>Hugo -- gohugo.io</generator><language>ko-KR</language><copyright>© nyan101</copyright><lastBuildDate>Sat, 12 Feb 2022 19:37:41 +0900</lastBuildDate><atom:link href="https://nyan101.github.io/category/%EC%9E%90%EC%8A%B5/feed.xml" rel="self" type="application/rss+xml"/><item><title>[PyTorch] 06. wandb로 학습 진행상황 로깅하기</title><link>https://nyan101.github.io/blog/notes-on-pytorch-06/</link><pubDate>Sat, 12 Feb 2022 19:37:41 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-06/</guid><description>&lt;h2 class="relative group"&gt;학습 진행상황 기록하기&#10; &lt;div id="학습-진행상황-기록하기" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%95%99%ec%8a%b5-%ec%a7%84%ed%96%89%ec%83%81%ed%99%a9-%ea%b8%b0%eb%a1%9d%ed%95%98%ea%b8%b0" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://nyan101.github.io/blog/notes-on-pytorch-04" target="_blank" rel="noreferrer"&gt;이전 글&lt;/a&gt;에서 작성한 코드는 &lt;code&gt;tqdm&lt;/code&gt; 라이브러리를 통해 &amp;ldquo;학습이 얼마나 진행되었는가&amp;quot;를 실시간으로 출력했다. 이를 통해 실행이 끝나기까지 막연히 기다리기만 하는 일반적인 코드와는 달리, 각 epoch당 남은 예상시간과 epoch별 train/val loss, accuracy를 출력해 학습이 진행됨에 따라 정확도가 높아지는 모습을 로그로 남길 수 있었다.&lt;/p&gt;</description></item><item><title>[PyTorch] 05. data.Dataset으로 나만의 Dataset 클래스 만들기</title><link>https://nyan101.github.io/blog/notes-on-pytorch-05/</link><pubDate>Wed, 09 Feb 2022 18:53:27 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-05/</guid><description>&lt;h2 class="relative group"&gt;자체 Dataset 클래스의 필요성&#10; &lt;div id="자체-dataset-클래스의-필요성" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9e%90%ec%b2%b4-dataset-%ed%81%b4%eb%9e%98%ec%8a%a4%ec%9d%98-%ed%95%84%ec%9a%94%ec%84%b1" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;지금까지의 실습에서는 &lt;code&gt;torchvision.datasets&lt;/code&gt;에서 제공하는 데이터셋을 사용했다. &lt;code&gt;torchvision&lt;/code&gt; 라이브러리는 vision과 관련된 약 30여개의 데이터셋을 제공하며, 전체 목록은 &lt;a href="https://pytorch.org/vision/stable/datasets.html" target="_blank" rel="noreferrer"&gt;공식 홈페이지&lt;/a&gt;에서 확인할 수 있다.&lt;/p&gt;&#10;&lt;p&gt;그러나 실습이나 연구를 진행하다 보면, 기존에 잘 알려진 데이터셋 외에 자신만의 데이터로 학습을 진행해야 하는 상황이 자주 발생한다. 이를 위해 &lt;code&gt;torch.utils.data.dataloader&lt;/code&gt;에 넘길 수 있는 나만의 &lt;code&gt;Dataset&lt;/code&gt; 객체를 만드는 법을 알아보자.&lt;/p&gt;</description></item><item><title>[PyTorch] 04. validation phase를 추가해 train_model() 함수 작성하기</title><link>https://nyan101.github.io/blog/notes-on-pytorch-04/</link><pubDate>Mon, 07 Feb 2022 20:38:11 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-04/</guid><description>&lt;p&gt;굉장히 오랜만에 이어지는 포스팅이다&amp;hellip; &lt;del&gt;핑거스냅에 당해서 블립(blip) 당함&lt;/del&gt;&lt;/p&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;모델 학습에서의 Training &amp;amp; Validation&#10; &lt;div id="모델-학습에서의-training--validation" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%aa%a8%eb%8d%b8-%ed%95%99%ec%8a%b5%ec%97%90%ec%84%9c%ec%9d%98-training--validation" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://nyan101.github.io/blog/notes-on-pytorch-03" target="_blank" rel="noreferrer"&gt;이전 글&lt;/a&gt;에서 작성했던 마지막 코드를 다시 살펴보자. 이전 글에서는 아래 5가지 단계를 거쳤다.&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;nn.Module&lt;/code&gt;을 상속받은 모델 클래스 작성&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;torchvision.datasets&lt;/code&gt; 라이브러리에서 유명 데이터셋(MNIST) 다운로드&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;torch.utils.data.Dataloader&lt;/code&gt; 사용법&lt;/li&gt;&#10;&lt;li&gt;모델의 1 epoch 학습 진행&lt;/li&gt;&#10;&lt;li&gt;모델의 test 성능 측정&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;각 단계별로 주요 로직을 정리해 하나의 코드로 합친 결과는 다음과 같다.&lt;/p&gt;</description></item><item><title>[ML] Knockoff Net: 랜덤한 입력으로 다른 모델을 모방할 수 있을까?</title><link>https://nyan101.github.io/blog/knockoff-net-with-complete-noise/</link><pubDate>Sun, 03 Nov 2019 11:12:33 +0900</pubDate><guid>https://nyan101.github.io/blog/knockoff-net-with-complete-noise/</guid><description>&lt;h2 class="relative group"&gt;발상: Knockoff Nets&#10; &lt;div id="발상-knockoff-nets" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%eb%b0%9c%ec%83%81-knockoff-nets" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;어제(2일) 대학원에서 Mario Fritz 박사님의 AI Security에 대한 강연을 들어볼 수 있었다. 딥러닝이 대세가 되면서 등장한 여러 보안 문제들에 대한 특강이었는데, 그중 Model Stealing(구체적으로는 Functionality Stealing)에 대해 다룬 &lt;a href="https://arxiv.org/abs/1812.02766" target="_blank" rel="noreferrer"&gt;knockoff-net&lt;/a&gt; 관련 내용이 흥미로워 pytorch로 구현해보았다. 다만 노트북이라는 한계로 원본 논문보다는 디테일을 다소 단순화했다(&amp;hellip;)&lt;/p&gt;</description></item><item><title>[PyTorch] 03. torch.nn 모듈 조립으로 CNN 만들기</title><link>https://nyan101.github.io/blog/notes-on-pytorch-03/</link><pubDate>Sun, 25 Aug 2019 16:39:46 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-03/</guid><description>&lt;h2 class="relative group"&gt;예제 dataset 가져오기&#10; &lt;div id="예제-dataset-가져오기" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%98%88%ec%a0%9c-dataset-%ea%b0%80%ec%a0%b8%ec%98%a4%ea%b8%b0" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;지금까지는 \(y=ax+b\)나 \(y=ax^2+bx+c\) 처럼 간단한 형태의 숫자→숫자 함수만을 모델링했으니 이제 좀더 흥미로운 데이터를 살펴보자.&lt;/p&gt;&#10;&lt;p&gt;딥러닝, 특히 이미지 인식 관련 예제를 보면 MNIST나 CIFAR-10같은 이름이 많이 등장한다. 이 둘은 Image Classification 문제의 대표적인 예시로 각각 손글씨와 물체 사진 이미지셋에 해당하며, 흔히 모델의 벤치마크 용도로 활용되고 있다. 이번 글에서는 좀더 단순한 MNIST를 사용하기로 한다. MNIST 데이터는 아래와 같이 색이 없는 1채널(=gray scale) 28x28픽셀 이미지들의 모음으로 0에서 9까지 총 10개의 라벨을 가지고 있다.&lt;/p&gt;</description></item><item><title>[PyTorch] 02. nn.Module로 모델 클래스 만들기</title><link>https://nyan101.github.io/blog/notes-on-pytorch-02/</link><pubDate>Tue, 20 Aug 2019 21:53:17 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-02/</guid><description>&lt;h2 class="relative group"&gt;학습의 각 단계를 추상화하기&#10; &lt;div id="학습의-각-단계를-추상화하기" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ed%95%99%ec%8a%b5%ec%9d%98-%ea%b0%81-%eb%8b%a8%ea%b3%84%eb%a5%bc-%ec%b6%94%ec%83%81%ed%99%94%ed%95%98%ea%b8%b0" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;앞서 그래디언트를 이용해 간단한 학습이 이루어지는 과정을 알아보았다. 이전 글의 마지막 코드를 다시 살펴보면 학습의 한 round를 크게 다음과 같은 단계들로 추상화시킬 수 있다.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_adjust&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 1) 파라미터를 이용해 입력(xs)으로부터 예상 결과를 생성&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2) 예상 결과(y_pred)와 실제 결과(ys)를 비교해 오차를 계산&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3) .backward()를 통해 각 파라미터가 오차에 관여하는 정도를 역산&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 4) 역산된 grad를 바탕으로 파라미터 수정 &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grad&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grad&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 5) 파라미터들의 grad값을 0으로 초기화&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grad&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero_&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grad&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero_&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;그런데 이번과 같이 모델이 \(y=ax+b\) 처럼 간단한 형태인 경우 파라미터(&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;)들을 각자 관리할 수 있지만, 복잡한 모델의 경우 이는 상당히 번거로운 과정이 될 수 있다. 흩어진 파라미터들을 통합해 관리한다면 어떤 형태가 가능할지 생각해 보자.&lt;/p&gt;</description></item><item><title>[PyTorch] 01. PyTorch의 기본 구조</title><link>https://nyan101.github.io/blog/notes-on-pytorch-01/</link><pubDate>Sun, 18 Aug 2019 22:00:21 +0900</pubDate><guid>https://nyan101.github.io/blog/notes-on-pytorch-01/</guid><description>&lt;p&gt;요새는 뭘 찾아봐도 딥러닝이 나온다..&lt;/p&gt;&#10;&lt;p&gt;성향이 continuous, gradient 같은 거랑은 안 맞아서 최대한 피해보려고 했지만 &lt;del&gt;결국 시대의 흐름에 거스르지 못하고&lt;/del&gt; 어떻게 사용하는지 정도는 알아두는게 좋을 것 같아서 정리해봤다.&lt;/p&gt;&#10;&#10;&#10;&lt;h4 class="relative group"&gt;요구사항(prerequisite)&#10; &lt;div id="요구사항prerequisite" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%9a%94%ea%b5%ac%ec%82%ac%ed%95%adprerequisite" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h4&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;python에 대한 기초지식 &lt;br&gt;&#10;(ex: &lt;code&gt;ABC.xyz()&lt;/code&gt;는 클래스/객체 &lt;code&gt;ABC&lt;/code&gt; 안에 있는 &lt;code&gt;xyz&lt;/code&gt; 라는 함수를 호출하는 것이다)&lt;/li&gt;&#10;&lt;li&gt;함수에 대한 개념(규칙에 따라 input → output으로 이어지는 블랙박스로 이해해도 된다)&lt;/li&gt;&#10;&lt;li&gt;머릿속 이미지화를 위한 약간의 상상력(?)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;tensor 클래스&#10; &lt;div id="tensor-클래스" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#tensor-%ed%81%b4%eb%9e%98%ec%8a%a4" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;tensor는 \(n\_1 \times n\_2 \times \cdots \times n\_d \) 개의 숫자를 \(d\)차원으로 정렬한 객체이다. 편의상 예시는 2차원 이하만을 다룰 예정이지만 임의의 차원을 가질 수 있다는 점은 알아두자.&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch04. Polymorphism &amp; Higher-Order Functions (2)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch04-2/</link><pubDate>Wed, 27 Feb 2019 19:47:20 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch04-2/</guid><description>&lt;h2 class="relative group"&gt;High-Order Functions&#10; &lt;div id="high-order-functions" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#high-order-functions" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;다른 함수를 다룰 수 있는 함수를 고차 함수(higher-order function)라고 한다.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Definition&lt;/span&gt; &lt;span class="n"&gt;do3times&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;Check&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;do3times&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;do3times&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;이 &lt;code&gt;do3times&lt;/code&gt;는 함수 f와 인자 a를 받아 a에 f를 3번 적용한 결과를 돌려준다. 함수를 인자로 제공한다는게 어떤 의미인지 살펴보자&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;Definition&lt;/span&gt; &lt;span class="n"&gt;doubleMe&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="kt"&gt;nat&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;nat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Compute&lt;/span&gt; &lt;span class="n"&gt;do3times&lt;/span&gt; &lt;span class="n"&gt;doubleMe&lt;/span&gt; &lt;span class="n"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;24&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;nat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;Filter&#10; &lt;div id="filter" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#filter" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;이제 좀더 유용한 고차 함수들에 대해 알아보자. filter는 X타입의 리스트(list X)와 원소 X에 대한 판정함수(predicate, \(f:X\rightarrow bool\))를 받아 주어진 predicate를 만족하는(i.e. true를 리턴하는) 원소들만을 남긴다.&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch04. Polymorphism &amp; Higher-Order Functions (1)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch04-1/</link><pubDate>Sun, 17 Feb 2019 22:22:37 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch04-1/</guid><description>&lt;h2 class="relative group"&gt;Polymorphic Lists&#10; &lt;div id="polymorphic-lists" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#polymorphic-lists" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;이전 장에서 natlist, 다시 말해 nat으로 이루어진 리스트에 대해 다뤘다. 마찬가지 방법으로 문자열 리스트, bool 리스트, 리스트의 리스트 등 다양한 리스트를 정의할 수 있다. 예를 들어 bool 리스트는&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Inductive&lt;/span&gt; &lt;span class="n"&gt;boollist&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bool_nil&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bool_cons&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;boollist&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;로 정의된다.&lt;/p&gt;&#10;&lt;p&gt;그런데 매번 새로운 타입의 리스트가 필요할 때마다 (거의) 동일한 정의를 다시 써주는 건 낭비일 것이다. 새로운 타입에 맞게 정의를 다시 쓴다는 말은 단순히 &lt;code&gt;nil&lt;/code&gt;이나 &lt;code&gt;cons&lt;/code&gt;의 문제가 아니라, length, reverse, append 등 앞서 natlist에서 정의했던 모든 함수를 전부 새로 작성해야 한다는 의미가 된다. 이런 불필요한 중복을 피하기 위해 Coq에서는 &lt;em&gt;다형적(polymorphic)&lt;/em&gt; 타입을 지원한다.&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch03. Working with Structured Data (2)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch03-2/</link><pubDate>Mon, 11 Feb 2019 22:01:56 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch03-2/</guid><description>&lt;h2 class="relative group"&gt;Reasoning About Lists&#10; &lt;div id="reasoning-about-lists" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#reasoning-about-lists" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;리스트에 대한 간단한 정리를 증명해보자.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Theorem&lt;/span&gt; &lt;span class="n"&gt;nil_app&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;natlist&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Proof&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kp"&gt;reflexivity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Qed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;대상이 natlist라는 점만 제외하면 이전의 &lt;code&gt;forall n:nat, 0+n=n&lt;/code&gt;과 같은 형태이다. nat에서와 마찬가지로 natlist도 &lt;code&gt;destruct&lt;/code&gt;를 통해 생성규칙에 따라 경우를 나눌 수 있다.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Theorem&lt;/span&gt; &lt;span class="n"&gt;tl_length_pred&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;natlist&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tl&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Proof&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;intros&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;destruct&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;[|&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;l&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;eqn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="c"&gt;(* l = [] *)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kp"&gt;reflexivity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="c"&gt;(* l = n::l&amp;#39; *)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kp"&gt;reflexivity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;마찬가지로 수학적 귀납법(induction tactic) 역시 적용 가능하다. nat에서의 귀납법과 마찬가지로 base step과 induction step으로 이루어져 있으며, 각각&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch03. Working with Structured Data (1)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch03-1/</link><pubDate>Sat, 09 Feb 2019 15:33:11 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch03-1/</guid><description>&lt;p&gt;본 챕터에서는 Structured Data, 그중에서도 List에 대해 다룬다.&lt;/p&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;Pairs of Numbers&#10; &lt;div id="pairs-of-numbers" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#pairs-of-numbers" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;지난번 &lt;code&gt;nybble&lt;/code&gt;을 정의할 때 언급했듯이, Coq의 생성자(constructor)는 여러 개의 인자를 받을 수 있다.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Inductive&lt;/span&gt; &lt;span class="n"&gt;natprod&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n1&lt;/span&gt; &lt;span class="n"&gt;n2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;nat&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;이렇게 정의된 &lt;code&gt;natprod&lt;/code&gt;에는 오직 하나의 생성규칙만 존재한다.(ex: &lt;code&gt;pair 3 5&lt;/code&gt;)&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch02. Proof by tactics (2)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch02-2/</link><pubDate>Sun, 03 Feb 2019 22:16:28 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch02-2/</guid><description>&lt;h2 class="relative group"&gt;Proof by Case Analysis&#10; &lt;div id="proof-by-case-analysis" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#proof-by-case-analysis" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;다뤄야 하는 대상이 복잡해지면 &lt;code&gt;simpl&lt;/code&gt;이나 &lt;code&gt;rewrite&lt;/code&gt;만으로는 충분하지 않은 경우가 있다. 잠시 &lt;a href="https://nyan101.github.io/blog/SW-Foundations-Ch01-2/" &gt;예전 글&lt;/a&gt;에서 정의했던 &lt;code&gt;is_equal&lt;/code&gt;을 가져오면서 여기에 새로운 Notation을 추가하자.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Fixpoint&lt;/span&gt; &lt;span class="n"&gt;is_equal&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;nat&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="n"&gt;m&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="n"&gt;n&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="n"&gt;m&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is_equal&lt;/span&gt; &lt;span class="n"&gt;n&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;m&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;end&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Notation&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;x =? y&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eqb&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="n"&gt;70&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nat_scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;이제 거의 비슷하게 생긴 다음 두 명제를 증명해보자.&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch02. Proof by tactics (1)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch02-1/</link><pubDate>Fri, 01 Feb 2019 20:15:17 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch02-1/</guid><description>&lt;p&gt;이제 Coq를 이용해 간단한 증명을 직접 작성해보자.&lt;/p&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;Notation&#10; &lt;div id="notation" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#notation" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;본론을 시작하기에 앞서 전에 만들었던 &lt;code&gt;plus&lt;/code&gt;, &lt;code&gt;mult&lt;/code&gt; 에 infix notation을 정의하자.&lt;/p&gt;&#10;&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-coq" data-lang="coq"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Notation&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;x + y&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="n"&gt;50&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt; &lt;span class="n"&gt;associativity&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nat_scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Notation&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;x * y&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mult&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="n"&gt;40&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;left&lt;/span&gt; &lt;span class="n"&gt;associativity&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nat_scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;이전에 &lt;code&gt;bool&lt;/code&gt;에 대해 &lt;code&gt;x &amp;amp;&amp;amp; y&lt;/code&gt; 를 정의하던 때보다 뭔가 이것저것 늘어났다. prefix, postfix notation과는 달리 infix notation에서는 모호한(ambiguous) 문장이 생길 수 있다. 일반적으로 (x+y*z)라는 표현식을 쓸 때 우리는 ((x+y)*z)가 아닌 (x+(y*z))를 의도한다. 위 코드에서의 역할을 간단히 요약하면&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch01. Functional Programming in Coq (2)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch01-2/</link><pubDate>Thu, 31 Jan 2019 20:01:32 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch01-2/</guid><description>&lt;h2 class="relative group"&gt;Define Numbers&#10; &lt;div id="define-numbers" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#define-numbers" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;이전 글에서는 &lt;code&gt;day&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt; 와 같이 원소의 개수가 유한한 타입, 다시 말해 타입 \(T\)에 대해 \(\{x \| x \mathrm\{\,has\,type\,\}T\} \)가 유한집합인 경우만을 다뤘다. 무한한 원소를 가지는 타입을 정의하려면 어떻게 해야 할까? 집합론에서와 마찬가지로 자연수에서 시작해보자. 페아노 공리계(&lt;a href="https://en.wikipedia.org/wiki/Peano_axioms#Formulation" target="_blank" rel="noreferrer"&gt;Peano axioms&lt;/a&gt;)에서 필요한 부분을 빌려오자. 크게 중요하지 않은 공리들은 생략했다&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch01. Functional Programming in Coq (1)</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch01-1/</link><pubDate>Tue, 29 Jan 2019 00:47:23 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch01-1/</guid><description>&lt;h2 class="relative group"&gt;Introduction&#10; &lt;div id="introduction" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#introduction" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&lt;p&gt;여기서는 Coq에서 사용되는 Galina라는 functional programming language의 기초적인 사용법과, Coq에서 증명에 실제 활용되는 기초적인 tactic에 대해 다룬다.&lt;/p&gt;&#10;&#10;&#10;&lt;h2 class="relative group"&gt;Data and Functions&#10; &lt;div id="data-and-functions" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#data-and-functions" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h2&gt;&#10;&#10;&#10;&lt;h3 class="relative group"&gt;Days of the Week&#10; &lt;div id="days-of-the-week" class="anchor"&gt;&lt;/div&gt;&#10; &#10; &lt;span&#10; class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;&#10; &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#days-of-the-week" aria-label="앵커"&gt;&lt;span class="heading-anchor-mark" aria-hidden="true"&gt;&lt;/span&gt;&lt;/a&gt;&#10; &lt;/span&gt;&#10; &#10;&lt;/h3&gt;&#10;&lt;p&gt;먼저 Coq에서 타입을 선언하는 법을 알아보자. 모든 Coq 구문은 .(마침표)로 끝남에 유의하자&lt;/p&gt;</description></item><item><title>[Coq 입문] Ch00. Overview</title><link>https://nyan101.github.io/blog/SW-Foundations-Ch00/</link><pubDate>Mon, 28 Jan 2019 21:02:16 +0900</pubDate><guid>https://nyan101.github.io/blog/SW-Foundations-Ch00/</guid><description>&lt;p&gt;Coq를 공부해보겠다는 막연한 목표와 함께 이런저런 자료를 찾아보고 그만두기를 반복하던 중, &lt;a href="https://deepspec.org/event/dsss18/" target="_blank" rel="noreferrer"&gt;DeepSpec Summer School&lt;/a&gt; 세미나에서 나온 영상을 발견했다. 유투브에서 찾은 다른 영상들이 4,5년 전 자료였던 반면 DeepSpec에서는 최근인 2017, 2018년까지 꾸준히 학습자료와 세미나 영상이 업로드되고 있다.&lt;/p&gt;&#10;&lt;p&gt;사실 예전 LaTeX을 익힐 때에도 이것저것 찾아보기만 하다가 결국 학교 과제를 LaTeX으로 작성해보고서야 익숙해졌는데, 이번에도 실 사용 없이 공부하는게 얼마나 갈지는 잘 모르겠다.. 자료 초반에 &lt;em&gt;&amp;ldquo;All the core chapters are suitable for both upper-level undergraduate and graduate students.&amp;rdquo;&lt;/em&gt; 라는 말이 있던데, &lt;del&gt;물론 저런 말들이 다 그렇듯이 전부 거짓말이겠지만&lt;/del&gt; 이젠 undergraduate 신분이라는 핑계도 사라졌으니 좀더 확실히 짚고 넘어가야겠다는 생각도 든다.&lt;/p&gt;</description></item></channel></rss>