{"id":1411,"date":"2020-04-17T03:22:18","date_gmt":"2020-04-17T03:22:18","guid":{"rendered":"http:\/\/sdi.thoughtstorms.info\/?p=1411"},"modified":"2020-04-17T03:22:18","modified_gmt":"2020-04-17T03:22:18","slug":"backlinks-in-cardigan-bay","status":"publish","type":"post","link":"https:\/\/blog.thoughtstorms.info\/?p=1411","title":{"rendered":"Backlinks in Cardigan Bay"},"content":{"rendered":"\n<p>People seem to be very excited about <a href=\"https:\/\/roamresearch.com\/\">Roam Research<\/a> at the moment. I&#8217;m sure it has many qualities. But I&#8217;m slightly surprised to realize that one thing that fans seem to find very useful (and almost miraculous) is the automatic back-linking. Ie, the ability to see what pages link to the page you are currently on.<\/p>\n\n\n<p>Bill Seitz has always been a <a href=\"http:\/\/webseitz.fluxent.com\/wiki\/BackLinks\">fan of this <\/a>feature, ensuring that it&#8217;s prominent on his WebSeitz engine. While, I confess, I&#8217;ve always thought that links that people bother to make <em>explicitly<\/em> are more interesting and should be valued more highly than links that are implicit.<\/p>\n\n\n<p>So, my current Python-based ThoughtStorms engine, following on from UseMod etc. lets you search for &#8220;pages that reference this one&#8221; with the usual text search, simply by clicking the page name, but it doesn&#8217;t automatically give backlinks to you on each page.<\/p>\n\n\n<p>But on ThoughtStorms you&#8217;ll see I do often explicitly put something like&nbsp; &#8220;Context : BlahPage, AnotherPage&#8221; at the top of pages where I think context is important.<\/p>\n\n\n<p>Nevertheless, automatic backlinks are clearly the fashion. And as I&#8217;m working on <em><a href=\"https:\/\/github.com\/interstar\/cardigan-bay\">Cardigan-bay: A new wiki engine in Clojure <\/a><\/em>I figured I might as well add this feature.<\/p>\n\n\n<p>So, one of the main ideas in Cardigan Bay is that it keeps an internal database of meta-data about the wiki, including which pages link to which, using <a href=\"https:\/\/github.com\/clojure\/core.logic\">core.logic, <\/a>Clojure&#8217;s standard <a href=\"http:\/\/minikanren.org\/\">miniKanren<\/a> library.<\/p>\n\n\n<p>So adding the backlinks feature is as simple as adding a core.logic query to this database.<\/p>\n\n\n<pre class=\"wp-block-code\"><code>(defn links-to [target]\n\u00a0 (pldb\/with-db @facts\n\u00a0\u00a0\u00a0 (logic\/run* [p q]\n\u00a0\u00a0\u00a0\u00a0\u00a0 (link p q)\n\u00a0\u00a0\u00a0\u00a0\u00a0 (page p)\n\u00a0\u00a0\u00a0\u00a0\u00a0 (page q)\n\u00a0\u00a0\u00a0\u00a0\u00a0 (logic\/== target q)\n\u00a0\u00a0 )))\n<\/code><\/pre>\n\n\n<p>That&#8217;s basically it. The logic query tests that there&#8217;s a link relation between <em>p<\/em> and <em>q<\/em>, that both <em>p<\/em> and <em>q<\/em> are actual&nbsp; existing pages, and that <em>q<\/em> is equal to the <em>target<\/em> argument to the Clojure function.<\/p>\n\n\n<p>This is pretty obvious and straightforward. So then I just create a card containing this data and attach it automatically to each page.<\/p>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/sdi.thoughtstorms.info\/wp-content\/uploads\/2020\/04\/Screenshot-from-2020-04-17-00-17-30-1.png\" alt=\"\" class=\"wp-image-1413\"\/><\/figure>\n\n\n<p>Took basically less than an hour to write the whole thing.<\/p>\n\n\n<p>And if you get the source from GitHub, it&#8217;s now there.<\/p>\n\n\n<p>However, right now this is fine for small wikis with a few pages. On the actual ThoughtStorms data (as you see in the screen shot above), which has over 4000 pages and an order of magnitude more links, it&#8217;s way too slow. So I&#8217;m going to have to figure out how (and more importantly, <em>where<\/em>) I&#8217;m going to cache the results. And when I have to recalculate them, etc.<\/p>\n\n\n<p>Nevertheless, automatic backlinks are now added to Cardigan Bay.<\/p>\n\n\n<p><strong>Update :<\/strong><\/p>\n\n\n<p>I just did a quick experiment where I took out the (page p) and (page q) clauses from the query. And it&#8217;s now <em>much<\/em> faster.<\/p>\n\n\n<p>Testing that the two pages exist doesn&#8217;t really matter much. There&#8217;s no real way we&#8217;re going to get a (link p q) clause if p doesn&#8217;t exist. And while there <em>can<\/em> be broken links ie. a (link p q) where q doesn&#8217;t exist, there&#8217;s no way we&#8217;ll actually be asking the backlink query about a q that doesn&#8217;t exist. So no need to join these extra clauses in. That makes this now a single match query on a single relation and much more tractable.<\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>People seem to be very excited about Roam Research at the moment. I&#8217;m sure it has many qualities. But I&#8217;m slightly surprised to realize that one thing that fans seem to find very useful (and almost miraculous) is the automatic back-linking. Ie, the ability to see what pages link to the page you are currently [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[38,57,252,284,336,360,503],"class_list":["post-1411","post","type-post","status-publish","format-standard","hentry","category-me","tag-bill-seitz","tag-cardigan-bay","tag-logic-programming","tag-minikanren","tag-personal-wiki","tag-prolog","tag-wiki-nature"],"_links":{"self":[{"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=\/wp\/v2\/posts\/1411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1411"}],"version-history":[{"count":0,"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=\/wp\/v2\/posts\/1411\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.thoughtstorms.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}