? users online
  • Logout
    • Open hangout
    • Open chat for current file
<div class="notebook open-fullscreen">

<div class="nb-cell markdown" name="md1">
# Space Age

**Also available for offline via [Gitlab](https://gitlab.com/PaulBrownMagic/PPFN/tree/master/SpaceAge).**

How old are you in Mercury years? How about Neptune years? Let's
find out with a fun little program. First the data, this is
how many planet years there are to one Earth year.
</div>

<div class="nb-cell program" data-background="true" name="p1">
%! year_ratio(+Planet, -Ratio) is det.
%  year ratio is the difference between
%  years on Earth and the Planet
year_ratio(mercury, 4.15).
year_ratio(venus, 1.62).
year_ratio(mars, 0.53).
year_ratio(jupiter, 0.08).
year_ratio(saturn, 0.03).
year_ratio(uranus, 0.01).
year_ratio(neptune, 0.006).
</div>

<div class="nb-cell markdown" name="md2">
## Learning

The other bit of information we need is the user's age. Let's ask
them what it is, and then remember it for later. This way when they
use the program, it will only ask them once. This is a good way to
get small bits of information in a small program. For larger use
cases, `assert/1` is a little inefficient.
</div>

<div class="nb-cell program" data-background="true" name="p2">
:- dynamic(known/2).
%! age(-Age) is det.
%  if we already know the user's age,
%  use that. Otherwise ask for it.
age(Age) :-
    known(age, Age), ! ;
    ask(age, Age).

%! ask(+Predicate, -Val) is det.
%  ask a user what the value is then
%  store their answer in memory.
ask(Predicate, Val) :-
    write("What is your "),
    write(Predicate),
    writeln("?"),
    read(Val),
    assert(known(Predicate, Val)).
</div>

<div class="nb-cell markdown" name="md3">
We can try this out, it remembers!
</div>

<div class="nb-cell markdown" name="md4">
We can try this out, it remembers! Except in SWISH this won't remember outside of a single query, it works better offline. 
</div>

<div class="nb-cell query" name="q1">
age(Age), age(Remember).
</div>

<div class="nb-cell markdown" name="md5">
## How old?!

Finally we need a predicate to calculate our spaceage. This looks
up the `year_ratio` for the planet, looks for the user's age (and
asks for it if needed), then calculates the PlanetAge.
</div>

<div class="nb-cell program" data-background="true" name="p3">
%! spaceage(+Planet, -PlanetAge) is det.
%  convert the user's age into Planet years.
spaceage(Planet, PlanetAge) :-
    year_ratio(Planet, Ratio),
    age(EarthAge),
    PlanetAge is EarthAge * Ratio.
</div>

<div class="nb-cell markdown" name="md6">
Try it out!
</div>

<div class="nb-cell query" name="q2">
spaceage(mars, SpaceAge).
</div>

</div>