Build client web apps with "Prolog"
Tags: blazor, prolog, spa
Published: 2021-01-05 05:53:05

---
title: Build client web apps with "Prolog"
published: true
description: This article describes about the library to make a Single Page client web Application with "Prolog" logic programming language.
tags: blazor, prolog, spa
cover_image: https://raw.githubusercontent.com/jsakamoto/Spprologa/main/SampleSite/SpprologaApp1/wwwroot/images/social-preview.png
---

# Do you known "Prolog"?

"Prolog" is a programming language that was developed in 1972.

Prolog is not "object-oriented programming language", not "functional programming language".
It is categorized into "**logic** programming language". 

Interestingly, in Prolog programming, programmers don't write operation sequences. 
Instead, they write "**facts**" and "**rules**" as a Prolog code. 

```prolog
human(socrates).
mortal(X) :- human(X).
```

After the Prolog runtime process the code, the user can ask the Prolog runtime to a query.

```prolog
?- mortal(X).
```

Then the Prolog runtime tries to find solutions to the query, and the runtime tells us solutions if they are found.

```prolog
X = socrates
```

I feel Prolog is a little bit strange and funny.
 
Before I know Prolog, I could not think that create a PC application written by only logical code, not procedure code.

# Can I create Single Page Web App with Prolog?

By the way, I have learned "Blazor" which is technology to create a Single Page Web Application (a.k.a "SPA")  with C#.

- _[Blazor | Build client web apps with C# | .NET](https://blazor.net)_

Blazor allows us to run .NET MSIL code on a web browser's WebAssembly engine.

And I know there is the Prolog interpreter "C#Prolog" written by C#.

- _[C#Prolog - A C# implementation of Prolog](https://github.com/jsakamoto/CSharpProlog)_

So, one day, I came up with the idea that **by combining Blazor and C# Prolog, I could create a SPA in Prolog**.

This Year-end and New Year vacations (2020-2021), I tried to realize that idea, and I did it finally.

# **"Spprologa"** - the library to make a SPA with Prolog

I published a new .NET library **"Spprologa"**.

- _[Spprologa - "Build client web apps with Prolog."](https://github.com/jsakamoto/Spprologa)_

"Spprologa" allows you to make a SPA with Prolog.

"Spprologa" means the initials of "**S**ingle **P**age **Prolog** **A**pplication".

Maybe as you know, due to this library built on Blazor and C#Prolog, all of the Prolog codes are **running inside of the Web browser**, not the server process.

The Prolog codes are interpreted by the interpreter (C#Prolog) that runs on the Web browser's WebAssembly engine, **not transpiled to JavaScript.**

This means "Spprologa" apps can be hosted on any HTTP servers that can serve at least static contents, such as GitHub Pages, Firebase, Netlify, Azure Static Web, etc.

You can see the live demo site (following URL) which deployed to GitHub Pages.

- ["Spprologa" live demo site](https://jsakamoto.github.io/Spprologa/)

# Let's programming the "Spprologa" app

![fig.1](https://raw.githubusercontent.com/jsakamoto/Spprologa/main/.assets/demo.gif)

## Prerequires

"Spprologa" is based on Blazor, therefore .NET SDK v.5.0.101 or later is required to develop a "Spprologa" application.
To install .NET SDK into your PC or Mac, please see also the following URL.

- _["Download .NET"](https://dotnet.microsoft.com/download)_

And I recommend installing the "Spprologa" project template by the following command, before starting "Spprologa" application programming.

```shell
$ dotnet new -i Spprologa.Templates::0.0.1-preview.4.0.0.0
```

## Create a new "Spprologa" app project , and run it.

Once the installation of the project template is complete, you can create a new "Spprologa" application project in the current folder by the `dotnet new` command.

```shell
$ dotnet new spprologa
```

After creating a new "Spprologa" application project, executing the following command starts building and running the app. And the application's URL will be opened by a default Web browser automatically.

```shell
$ dotnet watch run
```

## Publish the project

If you want to deploy the app to a Web server, execute the `dotnet publish` command like this:

```shell
$ dotnet publish -c:Release -o path/to/output
```

After executing the command above, all of the contents will be generated that are required to running the app in the `path/to/output/wwwroot` folder.

## Feature concepts

"Spprologa" application programming is based on 5 features as following.

### 1. `*.razor.prolog` files in the project are consulted automatically.

```prolog
% /Pages/Foo.razor.prolog
%   This Prolog code file will be consulted only once
%   when the "Foo.razor" component is first rendering.

input(name, "").

bird("swallow", canfly).
bird("penguin", canswim).
canfly(Name) :- bird(Name, canfly).

classify(Name, "can fly") :- canfly(Name).
classify(Name, "is bird, but can't fly.") :- bird(Name, _).
classify(_, "isn't bird.").

check :-
	input(name, Name), classify(Name, Message),
	retractall(message(_, _)), asserta(message(Name, Message)).
```

### 2. Bind result of a query to DOM contents.

Use **`@query("...")`** to retrieve a variable value inside a solution of a query which is specified as an argument, and render it as the HTML contents.

```html
<!-- /Pages/Foo.razor -->
...
<span>
  <!-- 👇 This code will render "swallow". -->
  @query("canfly(Name)")
</span>
```

### 3. Bind input to a fact.

Use **`@fact("...")`** to two way bind to an `input` element. 

```html
<!-- /Pages/Foo.razor -->
...
<input @bind='@fact("input(name, {0})").as_string' />
```

If the user inputs the text "gopher" into the `input` element above, then all `input(name, _)` facts will be retracted, and instead the fact `input(name, "gopher")` will be asserted.

### 4. Bind an action to a query.

Use **`@then("...")`** to make the query will be called when an event is fired.

```html
<!-- /Pages/Foo.razor -->
...
<button @onclick='@then("check")'>Check</button>
```

If the user clicks the button above, the query `check` will be called.

### 5. List up facts.

Use the **`<Case>`** component to retrieve all solutions of a query and render values of each solution to HTML contents.

```html
<!-- /Pages/Foo.razor -->
...
<ul>
  <Case Query="bird(Name, Ability)">
    <li>@context["Name"] - @context["Ability"]</li>
  </Case>
<ul>
```

The above code will render to HTML as follow:

```html
<ul>
  <li>swallow - canflay</li>
  <li>penguin - cannotflay</li>
</ul>
```

# What can "Spprologa" apps do?

As you know from my live demo site, I created a ["coloring map" solver](https://jsakamoto.github.io/Spprologa/mapcoloring).

![map coloring](https://dev-to-uploads.s3.amazonaws.com/i/kyr7nfiwd4zv9ujkiwwx.png)

The core code to resolve it is just the following.

```prolog
% define that what colors are there.
color(red).
color(green).
color(blue).
color(yellow).

% The implementation of the map coloring.
color_of_map(Alabama, Mississippi, Georgia, Tennessee, Florida) :-
    color(Alabama), color(Mississippi), color(Georgia), color(Tennessee), color(Florida),
    Tennessee \= Mississippi,
    Tennessee \= Alabama,
    Tennessee \= Georgia,
    Mississippi \= Alabama,
    Alabama \= Georgia,
    Alabama \= Florida,
    Georgia \= Florida.
```

And I also created ["Sudoku" (but this version 4 x 4 cells) solver](https://jsakamoto.github.io/Spprologa/4x4sudoku).

![Sudoku (4x4)](https://dev-to-uploads.s3.amazonaws.com/i/lt1y1k6tezq5u1q3xjh7.png)
The core code to the solver is just the following.

```prolog
sudoku(Puzzle, Solution) :-
    Solution = Puzzle,
    Puzzle = [
        S11, S12, S13, S14,
        S21, S22, S23, S24,
        S31, S32, S33, S34,
        S41, S42, S43, S44
    ],
    NUMBERS = [1,2,3,4],

    % rows
    permutation(NUMBERS, [S11, S12, S13, S14]),
    permutation(NUMBERS, [S21, S22, S23, S24]),
    permutation(NUMBERS, [S31, S32, S33, S34]),
    permutation(NUMBERS, [S41, S42, S43, S44]),

    % columns
    permutation(NUMBERS, [S11, S21, S31, S41]),
    permutation(NUMBERS, [S12, S22, S32, S42]),
    permutation(NUMBERS, [S13, S23, S33, S43]),
    permutation(NUMBERS, [S14, S24, S34, S44]),

    % square
    permutation(NUMBERS, [S11, S12, S21, S22]),
    permutation(NUMBERS, [S31, S32, S41, S42]),
    permutation(NUMBERS, [S13, S14, S23, S24]),
    permutation(NUMBERS, [S33, S34, S43, S44]).
```

Interestingly, **I didn't program any algorithms** to solve them.

Instead, **I only wrote constraints and rules** of those puzzles as a Prolog code.

I think this is the wonder and charm of Prolog programming.

# Notice: This is just "Proof of Concept"

"Spprologa" has been started by just only my interest that the "Prolog" can make a single page web app or not.
Therefore, **this library may be abandoned** after I lose interest in it.

However, this project is distributed under the Mozilla Public License.

So **anybody can fork** and **can continue this project freely anytime**, and I will strongly welcome it. 👍

**Have fun with Prolog programming!**