#!/usr/bin/perl use rel; declare { double => rel { alias my ($two, $one) = @_; oi => det { $two = $one * 2; }, io => det { $one = $two / 2; }, }, add => rel { alias my ($sum, $a, $b) = @_; oii => det { $sum = $a + $b; }, ioi => det { $a = $sum - $b; }, iio => det { $b = $sum - $a; }, }, mul => rel { alias my ($prod, $a, $b) = @_; oii => det { $prod = $a * $b; }, ioi => det { $a = $prod / $b; }, iio => det { $b = $prod / $a; }, }, square => rel { alias my ($square, $root) = @_; oi => det { $square = $root * $root; }, io => multi { if ($square > 0) { option { $root = sqrt($square) }; option { $root = -$root }; } elsif ($square == 0) { option { $root = 0 }; } }, }, split_join => rel { alias my ($list, $delim, $string) = @_; oii => det { @$list = split /\Q$delim\E/, $string, -1; }, iio => det { $string = join $delim, @$list; }, ioi => multi { # this mode is bogus / useless, but anyway it's a demo! my $split_len = 0; $split_len += length($_) for @$list; my $delim_len = (length($string) - $split_len) / (@$list-1); if ($delim_len >= 0 && is_int($delim_len)) { # TODO check all delimiters are the same? # but who cares, this is bogus anyway! option { $delim = substr $string, length($list->[0]//''), $delim_len; } } }, }, }; graph { our ($x, $y) = (7, undef); double($x, $y); solve { say $y; } $y; say defined $y ? "defined: $y" : "undef"; ($x, $y) = (undef, 2); solve { say $x; } $x; }; say; graph { my ($a, $b) = (9, undef); square($a, $b); solve_all { say $a, $b; }; }; say; graph { my ($a, $b, $c, $d, $e) = (81, undef, undef, 16, undef); square($a, $b); add($c, $b, $d); square($c, $e); solve { say $a, $b, $c, $d, $e; } $e; }; say; graph { my ($list, $delim, $string) = (undef, " ", "hello world this is nice"); split_join($list, $delim, $string); solve { say $_ for @$list; } $list; $list = [qw(wonderful library this is)]; $delim = '//'; $string = undef; solve_all { say $string; keep; }; $delim = undef; solve_all { say $delim; stop; }; $delim = '/'; $list = undef; solve_all { say @$list; keep }; $delim = ' AND '; undef $string; solve_all { say $string }; }; say; # TODO support tables / enumerated relations, and efficient joining / solving of those # TODO something so it can propogate changes: to values, lists, e.g. splice, # set value..., strings e.g. substr $foo, 5, 10, $bar, hashes / objects...