/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program nullobj64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szCarriageReturn:       .asciz "\n"
szMessResult:           .asciz "Value is null.\n"     // message result

qPtrObjet:              .quad 0                       // objet pointer
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main
main:                                                // entry of program

    ldr x0,qAdrqPtrObjet                             // load pointer address
    ldr x0,[x0]                                      // load pointer value
    cbnz x0,100f                                     // is null ?
    ldr x0,qAdrszMessResult                          // yes -> display message
    bl affichageMess

100:                                                 // standard end of the program
    mov x0,0                                         // return code
    mov x8,EXIT                                      // request to exit program
    svc 0                                            // perform the system call

qAdrszMessResult:        .quad szMessResult
qAdrszCarriageReturn:    .quad szCarriageReturn
qAdrqPtrObjet:           .quad qPtrObjet
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


TYPE Object=[
  BYTE byteData
  INT intData
  CARD cardData]

PROC IsNull(Object POINTER ptr)
  IF ptr=0 THEN
    PrintE("Object is null")
  ELSE
    PrintE("Object is not null")
  FI
RETURN

PROC Main()
  Object a
  Object POINTER ptr1=a,ptr2=0

  IsNull(ptr1)
  IsNull(ptr2)
RETURN


if (object == null)
    trace("object is null");


with Ada.Text_Io;

if Object = null then
   Ada.Text_Io.Put_line("object is null");
end if;


REF STRING no result = NIL;
STRING result := "";

IF no result :=: NIL THEN print(("no result :=: NIL", new line)) FI;
IF result :/=: NIL THEN print(("result :/=: NIL", new line)) FI;

IF no result IS NIL THEN print(("no result IS NIL", new line)) FI;
IF result ISNT NIL THEN print(("result ISNT NIL", new line)) FI;

COMMENT using the UNESCO/IFIP/WG2.1 ALGOL 68 character set
  result := °;
  IF REF STRING(result) :≠: ° THEN print(("result ≠ °", new line)) FI;
END COMMENT

# Note the following gotcha: #

REF STRING var := NIL;
IF var ISNT NIL THEN print(("The address of var ISNT NIL",new line)) FI;
IF var IS REF STRING(NIL) THEN print(("The address of var IS REF STRING(NIL)",new line)) FI


begin
    % declare a record type - will be accessed via references                %
    record R( integer f1, f2, f3 );
    % declare a reference to a R instance                                    %
    reference(R) refR;
    % assign null to the reference                                           %
    refR := null;
    % test for a null reference - will write "refR is null"                  %
    if refR = null then write( "refR is null" ) else write( "not null" );
end.


DEF x : PTR TO object
-> ...
IF object <> NIL
  -> ...
ENDIF


      ⍝⍝ GNU APL
      ]help ⍬
    niladic function: Z ← ⍬  (Zilde)
    Zilde is the empty numeric vector (aka. ⍳0)
Not a function but rather an alias for the empty
vector:
      ⍬≡⍳0
1


if x is missing value then
  display dialog "x is missing value"
end if

if x is null then
  display dialog "x is null"
end if


/* ARM assembly Raspberry PI  */
/*  program nullobj.s   */

/* Constantes    */
.equ STDIN,  0                                        @ Linux input console
.equ STDOUT, 1                                        @ Linux output console
.equ EXIT,   1                                        @ Linux syscall
.equ READ,   3                                        @ Linux syscall
.equ WRITE,  4                                        @ Linux syscall

/* Initialized data */
.data
szCarriageReturn:       .asciz "\n"
szMessResult:           .asciz "Value is null.\n"     @ message result

iPtrObjet:		.int 0                        @ objet pointer

/* UnInitialized data */
.bss

/*  code section */
.text
.global main
main:                                                @ entry of program

    ldr r0,iAdriPtrObjet                             @ load pointer address
    ldr r0,[r0]                                      @ load pointer value
    cmp r0,#0                                        @ is null ?
    ldreq r0,iAdrszMessResult                        @ yes -> display message
    bleq affichageMess

100:                                                 @ standard end of the program
    mov r0, #0                                       @ return code
    pop {fp,lr}                                      @ restaur 2 registers
    mov r7, #EXIT                                    @ request to exit program
    svc 0                                            @ perform the system call

iAdrszMessResult:        .int szMessResult
iAdrszCarriageReturn:    .int szCarriageReturn
iAdriPtrObjet:           .int iPtrObjet
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                           @ save  registres
    mov r2,#0                                       @ counter length
1:                                                  @ loop length calculation
    ldrb r1,[r0,r2]                                 @ read octet start position + index
    cmp r1,#0                                       @ if 0 its over
    addne r2,r2,#1                                  @ else add 1 in the length
    bne 1b                                          @ and loop
                                                    @ so here r2 contains the length of the message
    mov r1,r0                                       @ address message in r1
    mov r0,#STDOUT                                  @ code to write to the standard output Linux
    mov r7, #WRITE                                  @ code call system "write"
    svc #0                                          @ call systeme
    pop {r0,r1,r2,r7,lr}                            @ restaur des  2 registres */
    bx lr                                           @ return


If (object == null)
  MsgBox, object is null


Local $object = Null
If $object = Null Then MsgBox(0, "NULL", "Object is null")


#!/usr/bin/awk -f
BEGIN {
  b=0;
  print "<"b,length(b)">"
  print "<"u,length(u)">"
  print "<"u+0,length(u+0)">";
}


{ nil { nil? } { "Whew!\n" } { "Something is terribly wrong!\n" } ifte << }


TRUE = 1 : FALSE = 0
NULL = TRUE
IF NULL THEN PRINT "NULL"
NULL = FALSE
IF NOT NULL THEN PRINT "NOT NULL"


a:?x*a*?z  {assigns 1 to x and to z}
a:?x+a+?z  {assigns 0 to x and to z}
a:?x a ?z  {assigns "" (or (), which is equivalent) to x and to z}


#include <stdio.h>

int main()
{
	char *object = 0;

	if (object == NULL) {
		puts("object is null");
	}
	return 0;
}


if (foo == null)
    Console.WriteLine("foo is null");


#include <iostream>
#include <cstdlib>
if (object == 0) {
   std::cout << "object is null";
}


class C { };
var c:C; // is nil
writeln(if c == nil then "nil" else "something");


(let [x nil]
 (println "Object is" (if (nil? x) "nil" "not nil")))


       identification division.
       program-id. null-objects.
       remarks. test with cobc -x -j null-objects.cob

       data division.
       working-storage section.
       01 thing-not-thing      usage pointer.

      *> call a subprogram
      *>   with one null pointer
      *>   an omitted parameter
      *>   and expect void return (callee returning omitted)
      *>   and do not touch default return-code (returning nothing)
       procedure division.
       call "test-null" using thing-not-thing omitted returning nothing
       goback.
       end program null-objects.

      *> Test for pointer to null (still a real thing that takes space)
      *>   and an omitted parameter, (call frame has placeholder)
      *>   and finally, return void, (omitted)
       identification division.
       program-id. test-null.

       data division.
       linkage section.
       01 thing-one            usage pointer.
       01 thing-two            pic x.

       procedure division using
           thing-one
           optional thing-two
           returning omitted.

       if thing-one equal null then
           display "thing-one pointer to null" upon syserr
       end-if

       if thing-two omitted then
           display "no thing-two was passed" upon syserr
       end-if
       goback.
       end program test-null.


MODULE ObjectNil;
IMPORT StdLog;
TYPE
	Object = POINTER TO ObjectDesc;
	ObjectDesc = RECORD
	END;
VAR
	x: Object; (* default initialization to NIL *)

PROCEDURE DoIt*;
BEGIN
	IF x = NIL THEN
		StdLog.String("x is NIL");StdLog.Ln
	END
END DoIt;

END ObjectNil.


foo : Int32 | Nil = 5 # this variable's type can be Int32 or Nil
bar : Int32? = nil    # equivalent type to above, but shorter syntax
baz : Int32 = 5       # this variable can never be nil

foo.not_nil!          # nothing happens, since 5 is not nil
puts "Is foo nil? #{foo.nil?}"
foo = nil
puts "Now is foo nil? #{foo.nil?}"

puts "Does bar equal nil? #{bar == nil}"

puts "Is bar equivalent to nil? #{bar === nil}"

bar.not_nil!          # bar is nil, so an exception is thrown


import std.stdio;

class K {}

void main() {
    K k;
    if (k is null)
        writeln("k is null");
    k = new K;
    if (k !is null)
        writeln("Now k is not null");
}


  // the following are equivalent
  if lObject = nil then
  ...

  if not Assigned(lObject) then
  ...


var x = nil
if x == nil {
  //Do something
}


if not obj:
    pass #obj is seen as null

if = :nil obj:
    pass #obj is seen as null


null → null
() → null
(null? 3) → #f
(!null? 4) → #t
(null? null) → #t

;; careful - null is not false :
(if null 'OUI 'NON) → OUI

;; usual usage : recursion on lists until (null? list)
(define (f list)
    (when (!null? list)
    (write (first list)) (f (rest list))))

(f '( a b c))  →  a b c


class
	APPLICATION
inherit
	ARGUMENTS
create
	make

feature {NONE} -- Initialization

	make
		local
			i: INTEGER
			s: detachable STRING
		do
			if i = Void then
				print("i = Void")
			end
			if s = Void then
				print("s = Void")
			end
		end
end


iex(1)> nil == :nil
true
iex(2)> is_nil(nil)
true


let sl : string list = [null; "abc"]

let f s =
    match s with
    | null -> "It is null!"
    | _ -> "It's non-null: " + s

for s in sl do printfn "%s" (f s)


fansh> x := null
fansh> x == null
true
fansh> x = 1
1
fansh> x == null
false


'FB 1.05.0 Win64

' FreeBASIC does not have a NULL keyword but it's possible to create one using a macro

#Define NULL CPtr(Any Ptr, 0) '' Any Ptr is implicitly convertible to pointers of other types

Type Dog
  name As String
  age As Integer
End Type

Dim d As Dog Ptr = New Dog
d->Name = "Rover"
d->Age = 5
Print d->Name, d->Age
Delete d
d = NULL '' guard against 'd' being used accidentally in future

' in practice many FB developers would simply have written: d = 0 above
Sleep


package main

import "fmt"

var (
    s []int       // slice type
    p *int        // pointer type
    f func()      // function type
    i interface{} // interface type
    m map[int]int // map type
    c chan int    // channel type
)

func main() {
    fmt.Println(s == nil)
    fmt.Println(p == nil)
    fmt.Println(f == nil)
    fmt.Println(i == nil)
    fmt.Println(m == nil)
    fmt.Println(c == nil)
}


undefined      -- undefined value provided by the standard library
error "oops"   -- another undefined value
head []        -- undefined, you can't take the head of an empty list


procedure main()
nulltest("a",a)                # unassigned variables are null by default
nulltest("b",b := &null)       # explicit assignment is possible
nulltest("c",c := "anything")
nulltest("c",c := &null)       # varibables can't be undefined
end

procedure nulltest(name,var)
return write(name, if /var then " is" else " is not"," null.")
end


if(object == nil, "object is nil" println)


// here "object" is a reference
if (object == null) {
   System.out.println("object is null");
}


if (object === null) {
  alert("object is null");
  // The object is nothing
}

typeof null === "object"; // This stands since the beginning of JavaScript


null|type      # => "null"

null == false  # => false

null == null   # => true

empty|type     # =>  # i.e. nothing (as in, nada)

empty == empty # =>  # niente

empty == "black hole" # =>  # Ничего


/* null non value */

if (thing == null) { puts("thing tests as null"); }
if (thing === undefined) { puts("thing strictly tests as undefined"); }
puts(typeof thing);
puts(typeof null);
puts(typeof undefined);


  (1;;2) ~ (1 ; _n ; 2)    /  ~  is ''identical to'' or ''match'' .
1
  _n ~' ( 1 ; ; 2 )        /  ''match each''
0 1 0

additional properties :  [email protected] and _n?i are i; _n`v is _n


// version 1.1.0

fun main(args: Array<String>) {
    val i: Int  = 3           // non-nullable Int type - can't be assigned null
    println(i)
    val j: Int? = null        // nullable Int type - can be assigned null
    println(j)
    println(null is Nothing?) // test that null is indeed of type Nothing?
}


val .x, .y = true, null

writeln .x == null
writeln .y == null
writeln .x ==? null
writeln .y ==? null

# null not a "truthy" result
writeln if(null: 0; 1)


local(x = string, y = null)
#x->isA(::null)
// 0 (false)

#y->isA(::null)
// 1 (true)

#x == null
// false

#y == null
//true

#x->type == 'null'
// false

#y->type == 'null'
//true


foo := Nil.
if { foo nil?. } then {
  putln: "Foo is nil".
} else {
  putln: "Foo is not nil".
}.


enum class Option[A] {
  Some(A)
  None
}

# Only variables of class Option can be assigned to None.

# Type: Option[integer]
var v = Some(10)

# Valid: v is an Option, and any Option can be assigned to None
v = None

# Invalid! v is an Option[integer], not just a plain integer.
v = 10

# Type: integer
var w = 10

# Invalid! Likewise, w is an integer, not an Option.
w = None


put _global.doesNotExist
-- <Void>

put voidP(_global.doesNotExist)
-- 1

x = VOID
put x
-- <Void>

put voidP(x)
-- 1


to test :thing
if empty? :thing [print [list or word is empty]]
end

print empty? []  ; true
print empty? "|| ; true


Module CheckWord {
      Declare Alfa "WORD.APPLICATION"
      Declare Alfa Nothing
      Print Type$(Alfa)="Nothing"
      Try ok {
            Declare Alfa "WORD.APPLICATION"
            \\ we can't declare again Alfa

      }
      If Not Ok Then Print Error$  ' return Bad Object declaration
}
CheckWord


a := NULL;
                                                         a :=
is (NULL = ());
                                                         true
if a = NULL then
    print (NULL);
end if;


a = []; b='';
isempty(a)
isempty(b)
if (a)
  1,
else,
  0
end;


if obj == undefined then print "Obj is undefined"


CACHE>WRITE $DATA(VARI)
0
CACHE>SET VARI="HELLO" WRITE $DATA(VARI)
1
CACHE>NEW VARI WRITE $DATA(VARI) ;Change to a new scope
0
CACHE 1S1>SET VARI(1,2)="DOWN" WRITE $DATA(VARI)
10
CACHE 1S1>WRITE $DATA(VARI(1))
10
CACHE 1S1>WRITE $D(VARI(1,2))
1
CACHE 1S1>SET VARI(1)="UP" WRITE $DATA(VARI(1))
11
<CACHE 1S1>QUIT ;Leave the scope

<CACHE>W $DATA(VARI)," ",VARI
1 HELLO


$x = $null

if ($x = $null)
	println "x is null"
else
	println "x is not null"
end if


/**
 <doc>

Neko uses null for undefined variables,
  and also as a programmer accessible value.

The null value can be treated as a boolean value with the
  builtin $istrue, and tests as false.

 </doc>
*/

var n = null
if n == null $print("n is null\n")
if $not($istrue(n)) $print("and tests as boolean false\n")


/* NetRexx */
options replace format comments java crossref symbols binary

robject = Rexx -- create an object for which the value is undefined
say String.valueOf(robject) -- will report the text "null"
if robject = null then say 'Really, it''s "null"!'


#! /usr/local/bin/newlisp
(setq myobject nil)
(println (nil? myobject))
(exit)


let s: pointer = nil

{.experimental: "notnil".}
let ns: pointer not nil = nil # Compile time error


MODULE Null;
IMPORT
  Out;
TYPE
  Object = POINTER TO ObjectDesc;
  ObjectDesc = RECORD
  END;

VAR
  o: Object;  (* default initialization to NIL *)

BEGIN
  IF o = NIL THEN Out.String("o is NIL"); Out.Ln END
END Null.


# here "object" is a reference
if(object = Nil) {
   "object is null"->PrintLine();
};


// here "object" is an object pointer
if (object == nil) {
   NSLog("object is nil");
}


null isNull
"abcd" isNull
: testNull { | a | a ifNull: [ "Variable value is null" println ] ;


if a[i] == .nil then say "Item" i "is missing"


print defined($x) ? 'Defined' : 'Undefined', ".\n";


type nullableString(object o)
    return string(o) or o=NULL
end type
nullableString s
s = "hello"
s = NULL
--s = 1 -- error
--s = {1,2,3} -- error

type nullableSequence(object o)
    return sequence(o) or o=NULL
end type
nullableSequence q
q = {1,2,3}
q = "string"    -- fine (strings are a subset of sequences)
q = NULL
--q = 1         -- error


if (obj == null) printf("obj is null!\n");


$x = NULL;
if (is_null($x))
  echo "\$x is null\n";


(if (not MyNewVariable)
   (handle value-is-NIL) )


> mapping bar;
> bar;
Result: 0
> bar = ([ "foo":0 ]);
> bar->foo;
Result 0;
> zero_type(bar->foo);
Result: 0
> bar->baz;
Result: 0
> zero_type(bar->baz);
Result: 1


declare x fixed decimal (10);
...
if ^valid(x) then signal error;

declare y picture 'A9XAAA9';
...
if ^valid(y) then signal error;


If variable = #Null
  Debug "Variable has no value"
EndIf


x = None
if x is None:
  print "x is None"
else:
  print "x is not None"


is.null(NULL)       # TRUE
is.null(123)        # FALSE
is.null(NA)         # FALSE
123==NULL           # Empty logical value, with a warning
foo <- function(){} # function that does nothing
foo()               # returns NULL


-> null
'()
-> (null? null)
#t
-> (null? 3)
#f


my $var;
say $var.WHAT;      # Any()
$var = 42;
say $var.WHAT;      # Int()
say $var.defined;   # True
$var = Nil;
say $var.WHAT;      # Any()
say $var.defined    # False


NULL as $v
$v NULL =     # TRUE
$v NULL !=    # FALSE

1 NULL =      # FALSE
1.1 NULL =    # FALSE

NULL as $v2
$v2 $v =      # TRUE


x: none

print ["x"  either none? x ["is"]["isn't"]  "none."]


/*REXX program demonstrates null strings, and also undefined values. */

if symbol('ABC')=="VAR" then say 'variable ABC is defined, value='abc"<<<"
                        else say "variable ABC isn't defined."
xyz=47
if symbol('XYZ')=="VAR" then say 'variable XYZ is defined, value='xyz"<<<"
                        else say "variable XYZ isn't defined."
drop xyz
if symbol('XYZ')=="VAR" then say 'variable XYZ is defined, value='xyz"<<<"
                        else say "variable XYZ isn't defined."
cat=''
if symbol('CAT')=="VAR" then say 'variable CAT is defined, value='cat"<<<"
                        else say "variable CAT isn't defined."


see isnull(5) + nl +        # print 0
isnull("hello") + nl +      # print 0
isnull([1,3,5]) + nl +      # print 0
isnull("") + nl +           # print 1
isnull("NULL")              # print 1


puts "@object is nil" if @object.nil?		# instance variable

puts "$object is nil" if $object.nil?		# global variable, too

# It recognizes as the local variable even if it isn't executed.
object = 1  if false
puts "object is nil" if object.nil?

# nil itself is an object:
puts nil.class  # => NilClass


// If an option may return null - or nothing - in Rust, it's wrapped
// in an Optional which may return either the type of object specified
// in <> or None. We can check this using .is_some() and .is_none() on
// the Option.

fn check_number(num: &Option<u8>) {
    if num.is_none() {
        println!("Number is: None");
    } else {
        println!("Number is: {}", num.unwrap());
    }
}

fn main() {
    let mut possible_number: Option<u8> = None;
    check_number(&possible_number);

    possible_number = Some(31);
    check_number(&possible_number);
}


variable foo = NULL;
print(foo);
if (foo == NULL)
   print(typeof(foo));


scala> Nil
res0: scala.collection.immutable.Nil.type = List()

scala> Nil == List()
res1: Boolean = true

scala> Null
<console>:8: error: not found: value Null
              Null
              ^

scala> null
res3: Null = null

scala> None
res4: None.type = None

scala> Unit
res5: Unit.type = object scala.Unit

scala> val a = println()
a: Unit = ()


var undefined;         # initialized with an implicit nil
say undefined==nil;    # true
say defined(nil)       # false


object isNil ifTrue: [ "true block" ]
             ifFalse: [ "false block" ].
nil isNil ifTrue: [ 'true!' displayNl ]. "output: true!"
foo isNil ifTrue: [ 'ouch' displayNl ].
x := (foo == nil).
x := foo isNil


templates mightBeNothing
  when <=0> do !VOID
  when <=1> do 'something' !
end mightBeNothing

1 -> mightBeNothing -> 'Produced $;. ' -> !OUT::write

0 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write
2 -> mightBeNothing -> 'Won''t execute this' -> !OUT::write

// capture the transform in a list to continue computation when no result is emitted
[1 -> mightBeNothing] -> \(
  when <=[]> 'Produced nothing. ' !
  otherwise 'Produced $(1);. ' !
\) -> !OUT::write

[0 -> mightBeNothing] -> \(
  when <=[]> 'Produced nothing. ' !
  otherwise 'Produced $(1);. ' !
\) -> !OUT::write

[2 -> mightBeNothing] -> \(
  when <=[]> 'Produced nothing. ' !
  otherwise 'Produced $(1);. ' !
\) -> !OUT::write


# the type at declaration doesn't matter
decl int x

set x null
if (= x null)
    out "x is null" endl console
else
    out "x is not null" endl console
end if


Public Sub Main()
    Dim c As VBA.Collection

    ' initial state: Nothing
    Debug.Print c Is Nothing

    ' create an instance
    Set c = New VBA.Collection
    Debug.Print Not c Is Nothing

    ' release the instance
    Set c = Nothing
    Debug.Print c Is Nothing
End Sub


Public Sub Main()
Dim c As VBA.Collection

' initial state: Nothing
Debug.Assert c Is Nothing

' create an instance
Set c = New VBA.Collection
Debug.Assert Not c Is Nothing

' release the instance
Set c = Nothing
Debug.Assert c Is Nothing

End Sub


// Declare a variable without giving it an explicit value.
var s

// We can now check for nullness in one of these ways.
System.print(s)
System.print(s == null)
System.print(s is Null)
System.print(s.type == Null)

// Similarly, if we define this function without giving it a return value.
var f = Fn.new {
    System.print("I'm a function with no explicit return value.")
}

// And now call it.
var g = f.call()
// We find that the return value is null.
System.print(g)


generic
   type Real is digits <>;
   with function Sqrt(X: Real) return Real;
   with function "**"(X: Real; Y: Real) return Real;
package Approximation is

   type Number is private;

   -- create an approximation
   function Approx(Value: Real; Sigma: Real) return Number;

   -- unary operations and conversion Real to Number
   function "+"(X: Real) return Number;
   function "-"(X: Real) return Number;
   function "+"(X: Number) return Number;
   function "-"(X: Number) return Number;

   -- addition / subtraction
   function "+"(X: Number; Y: Number) return Number;
   function "-"(X: Number; Y: Number) return Number;

   -- multiplication / division
   function "*"(X: Number; Y: Number) return Number;
   function "/"(X: Number; Y: Number) return Number;

   -- exponentiation
   function "**"(X: Number; Y: Positive) return Number;
   function "**"(X: Number; Y: Real) return Number;

   -- Output to Standard IO (wrapper for Ada.Text_IO and Ada.Text_IO.Float_IO)
   procedure Put_Line(Message: String;
                      Item: Number;
                      Value_Fore: Natural := 7;
                      Sigma_Fore: Natural := 4;
                      Aft:  Natural := 2;
                      Exp:  Natural := 0);
   procedure Put(Item: Number;
                 Value_Fore: Natural := 7;
                 Sigma_Fore: Natural := 3;
                 Aft:  Natural := 2;
                 Exp:  Natural := 0);

private
   type Number is record
      Value: Real;
      Sigma: Real;
   end record;
end Approximation;


# MODE representing a uncertain number #
MODE UNCERTAIN = STRUCT( REAL v, uncertainty );

# add a costant and an uncertain value #
OP + = ( INT  c, UNCERTAIN u )UNCERTAIN: UNCERTAIN( v OF u + c, uncertainty OF u );
OP + = ( UNCERTAIN u, INT  c )UNCERTAIN: c + u;
OP + = ( REAL c, UNCERTAIN u )UNCERTAIN: UNCERTAIN( v OF u + c, uncertainty OF u );
OP + = ( UNCERTAIN u, REAL c )UNCERTAIN: c + u;
# add two uncertain values #
OP + = ( UNCERTAIN a, b )UNCERTAIN: UNCERTAIN( v OF a + v OF b
                                             , sqrt( ( uncertainty OF a * uncertainty OF a )
                                                   + ( uncertainty OF b * uncertainty OF b )
                                                   )
                                             );

# negate an uncertain value #
OP - = ( UNCERTAIN a )UNCERTAIN: ( - v OF a, uncertainty OF a );

# subtract an uncertain value from a constant #
OP - = ( INT  c, UNCERTAIN u )UNCERTAIN: c + - u;
OP - = ( REAL c, UNCERTAIN u )UNCERTAIN: c + - u;
# subtract a constant from an uncertain value #
OP - = ( UNCERTAIN u, INT  c )UNCERTAIN: u + - c;
OP - = ( UNCERTAIN u, REAL c )UNCERTAIN: u + - c;
# subtract two uncertain values #
OP - = ( UNCERTAIN a, b )UNCERTAIN: a + - b;

# multiply a constant by an uncertain value #
OP * = ( INT  c, UNCERTAIN u )UNCERTAIN: UNCERTAIN( v OF u + c, ABS( c * uncertainty OF u ) );
OP * = ( UNCERTAIN u, INT  c )UNCERTAIN: c * u;
OP * = ( REAL c, UNCERTAIN u )UNCERTAIN: UNCERTAIN( v OF u + c, ABS( c * uncertainty OF u ) );
OP * = ( UNCERTAIN u, REAL c )UNCERTAIN: c * u;
# multiply two uncertain values #
OP * = ( UNCERTAIN a, b )UNCERTAIN:
   BEGIN
       REAL av = v OF a;
       REAL bv = v OF b;
       REAL f  = av * bv;
       UNCERTAIN( f, f * sqrt( ( uncertainty OF a / av ) + ( uncertainty OF b / bv ) ) )
   END # * # ;

# construct the reciprocol of an uncertain value #
OP ONEOVER = ( UNCERTAIN u )UNCERTAIN: ( 1 / v OF u, uncertainty OF u );
# divide a constant by an uncertain value #
OP / = ( INT  c, UNCERTAIN u )UNCERTAIN: c * ONEOVER u;
OP / = ( REAL c, UNCERTAIN u )UNCERTAIN: c * ONEOVER u;
# divide an uncertain value by a constant #
OP / = ( UNCERTAIN u, INT  c )UNCERTAIN: u * ( 1 / c );
OP / = ( UNCERTAIN u, REAL c )UNCERTAIN: u * ( 1 / c );
# divide two uncertain values #
OP / = ( UNCERTAIN a, b )UNCERTAIN: a * ONEOVER b;

# exponentiation #
OP ^ = ( UNCERTAIN u, INT c )UNCERTAIN:
   BEGIN
       REAL f = v OF u ^ c;
       UNCERTAIN( f, ABS ( ( f * c * uncertainty OF u ) / v OF u ) )
   END # ^ # ;
OP ^ = ( UNCERTAIN u, REAL c )UNCERTAIN:
   BEGIN
       REAL f = v OF u ^ c;
       UNCERTAIN( f, ABS ( ( f * c * uncertainty OF u ) / v OF u ) )
   END # ^ # ;

# test the above operatrs by using them to find the pythagorean distance between the two sample points #
UNCERTAIN x1 = UNCERTAIN( 100, 1.1 );
UNCERTAIN y1 = UNCERTAIN(  50, 1.2 );
UNCERTAIN x2 = UNCERTAIN( 200, 2.2 );
UNCERTAIN y2 = UNCERTAIN( 100, 2.3 );

UNCERTAIN d  = ( ( ( x1 - x2 ) ^ 2 ) + ( y1 - y2 ) ^ 2 ) ^ 0.5;

print( ( "distance: ", fixed( v OF d, 0, 2 ), " +/- ", fixed( uncertainty OF d, 0, 2 ), newline ) )


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

typedef struct{
    double value;
    double delta;
}imprecise;

#define SQR(x) ((x) * (x))
imprecise imprecise_add(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value + b.value;
    ret.delta = sqrt(SQR(a.delta) + SQR(b.delta));
    return ret;
}

imprecise imprecise_mul(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value * b.value;
    ret.delta = sqrt(SQR(a.value * b.delta) + SQR(b.value * a.delta));
    return ret;
}

imprecise imprecise_div(imprecise a, imprecise b)
{
    imprecise ret;
    ret.value = a.value / b.value;
    ret.delta = sqrt(SQR(a.value * b.delta) + SQR(b.value * a.delta)) / SQR(b.value);
    return ret;
}

imprecise imprecise_pow(imprecise a, double c)
{
    imprecise ret;
    ret.value = pow(a.value, c);
    ret.delta = fabs(ret.value * c * a.delta / a.value);
    return ret;
}

char* printImprecise(imprecise val)
{
	char principal[30],error[30],*string,sign[2];
	sign[0] = 241;    /* ASCII code for ±, technical notation for denoting errors */
	sign[1] = 00;

	sprintf(principal,"%f",val.value);
	sprintf(error,"%f",val.delta);

	string = (char*)malloc((strlen(principal)+1+strlen(error)+1)*sizeof(char));

	strcpy(string,principal);
	strcat(string,sign);
	strcat(string,error);

	return string;
}

int main(void) {
    imprecise x1 = {100, 1.1};
    imprecise y1 = {50, 1.2};
    imprecise x2 = {-200, 2.2};
    imprecise y2 = {-100, 2.3};
    imprecise d;

    d = imprecise_pow(imprecise_add(imprecise_pow(imprecise_add(x1, x2), 2),imprecise_pow(imprecise_add(y1, y2), 2)), 0.5);
    printf("Distance, d, between the following points :");
    printf("\n( x1, y1) = ( %s, %s)",printImprecise(x1),printImprecise(y1));
    printf("\n( x2, y2) = ( %s, %s)",printImprecise(x2),printImprecise(y2));
    printf("\nis d = %s", printImprecise(d));
    return 0;
}


#pragma once

#include <cmath>
#include <string>
#include <sstream>
#include <iomanip>

class Approx {
public:
    Approx(double _v, double _s = 0.0) : v(_v), s(_s) {}

    operator std::string() const {
        std::ostringstream os("");
        os << std::setprecision(15) << v << " ±" << std::setprecision(15) << s << std::ends;
        return os.str();
    }

    Approx operator +(const Approx& a) const { return Approx(v + a.v, sqrt(s * s + a.s * a.s)); }
    Approx operator +(double d) const { return Approx(v + d, s); }
    Approx operator -(const Approx& a) const { return Approx(v - a.v, sqrt(s * s + a.s * a.s)); }
    Approx operator -(double d) const { return Approx(v - d, s); }

    Approx operator *(const Approx& a) const {
        const double t = v * a.v;
        return Approx(v, sqrt(t * t * s * s / (v * v) + a.s * a.s / (a.v * a.v)));
    }

    Approx operator *(double d) const { return Approx(v * d, fabs(d * s)); }

    Approx operator /(const Approx& a) const {
        const double t = v / a.v;
        return Approx(t, sqrt(t * t * s * s / (v * v) + a.s * a.s / (a.v * a.v)));
    }

    Approx operator /(double d) const { return Approx(v / d, fabs(d * s)); }

    Approx pow(double d) const {
        const double t = ::pow(v, d);
        return Approx(t, fabs(t * d * s / v));
    }

private:
    double v, s;
};


(defstruct uncertain-number
  (value 0 :type number)
  (uncertainty 0 :type number))

(defmethod print-object ((n uncertain-number) stream)
  (format stream "~,2F ± ~,2F" (uncertain-number-value n) (uncertain-number-uncertainty n)))

(defun ~+ (n1 n2)
  (let* ((value1 (uncertain-number-value n1))
         (value2 (uncertain-number-value n2))
         (uncertainty1 (uncertain-number-uncertainty n1))
         (uncertainty2 (uncertain-number-uncertainty n2))
         (value (+ value1 value2))
         (uncertainty (sqrt (+ (* uncertainty1 uncertainty1)
                               (* uncertainty2 uncertainty2)))))
    (make-uncertain-number :value value :uncertainty uncertainty)))

(defun negate (n)
  (make-uncertain-number :value (- (uncertain-number-value n))
                         :uncertainty (uncertain-number-uncertainty n)))

(defun ~- (n1 n2)
  (~+ n1 (negate n2)))

(defun ~* (n1 n2)
  (let* ((value1 (uncertain-number-value n1))
         (value2 (uncertain-number-value n2))
         (uncertainty-ratio-1 (/ (uncertain-number-uncertainty n1) value1))
         (uncertainty-ratio-2 (/ (uncertain-number-uncertainty n2) value2))
         (value (* value1 value2))
         (uncertainty (sqrt (* value
                               value
                               (+ (* uncertainty-ratio-1 uncertainty-ratio-1)
                                  (* uncertainty-ratio-2 uncertainty-ratio-2))))))
    (make-uncertain-number :value value :uncertainty uncertainty)))

(defun inverse (n)
  (make-uncertain-number :value (/ (uncertain-number-value n))
                         :uncertainty (uncertain-number-uncertainty n)))

(defun ~/ (n1 n2)
  (~* n1 (inverse n2)))

(defun ~expt (base exp)
  (let* ((base-value (uncertain-number-value base))
         (uncertainty-ratio (/ (uncertain-number-uncertainty base) base-value))
         (value (expt base-value exp))
         (uncertainty (abs (* value exp uncertainty-ratio))))
    (make-uncertain-number :value value :uncertainty uncertainty)))

(defun solve ()
  (let* ((x1 (make-uncertain-number :value 100 :uncertainty 1.1))
         (y1 (make-uncertain-number :value  50 :uncertainty 1.2))
         (x2 (make-uncertain-number :value 200 :uncertainty 2.2))
         (y2 (make-uncertain-number :value 100 :uncertainty 2.3))
         (d  (~expt (~+ (~expt (~- x1 x2) 2) (~expt (~- y1 y2) 2))
                    1/2)))
    (format t "d = ~A~%" d)))


import std.stdio, std.math, std.string, std.typecons, std.traits;

const struct Imprecise {
    private const double value, delta;

    this(in double v, in double d) pure nothrow {
        this.value = v;
        this.delta = abs(d);
    }

    enum IsImprecise(T) = is(Unqual!T == Unqual!(typeof(this)));

    I reciprocal() const pure nothrow {
        return I(1.0 / value, delta / (value ^^ 2));
    }

    string toString() const {
        return format("I(value=%g, delta=%g)", value, delta);
    }

    I opUnary(string op:"-")() const pure nothrow {
        return I(-this.value, this.delta);
    }

    I opBinary(string op:"+", T)(in T other) const pure nothrow
    if (isNumeric!T || IsImprecise!T) {
        static if (IsImprecise!T)
            return I(this.value + other.value,
                     (this.delta ^^ 2 + other.delta ^^ 2) ^^ 0.5);
        else
            return I(this.value + other, this.delta);
    }

    I opBinaryRight(string op:"+", T)(in T other) const pure nothrow
    if (isNumeric!T) {
        return I(this.value + other, this.delta);
    }

    I opBinary(string op:"-", T)(in T other) const pure nothrow
    if (isNumeric!T || IsImprecise!T) {
        return this + (-other);
    }

    I opBinaryRight(string op:"-", T)(in T other) const pure nothrow
    if (isNumeric!T) {
        return this - other;
    }

    I opBinary(string op:"*", T)(in T other) const pure nothrow
    if (isNumeric!T || IsImprecise!T) {
        static if (IsImprecise!T) {
            auto f = this.value * other.value;
            return I(f, f * ((delta / value) ^^ 2 +
                     (other.delta / other.value) ^^ 2) ^^ 0.5);
        } else
            return I(this.value * other, this.delta * other);
    }

    I opBinaryRight(string op:"*", T)(in T other) const pure nothrow
    if (isNumeric!T) {
        return this * other;
    }

    I opBinary(string op:"/", T)(in T other) const pure nothrow
    if (isNumeric!T || IsImprecise!T) {
        static if (IsImprecise!T)
            return this * other.reciprocal();
        else
            return I(this.value / other, this.delta / other);
    }

    I opBinaryRight(string op:"/", T)(in T other) const pure nothrow
    if (isNumeric!T) {
        return this / other;
    }

    I opBinary(string op:"^^", T)(in T other) const pure nothrow
    if (isNumeric!T) {
        auto f = this.value ^^ other;
        return I(f, f * other * (this.delta / this.value));
    }
}

alias I = Imprecise;

auto distance(T1, T2)(in T1 p1, in T2 p2) pure nothrow {
    return ((p1[0] - p2[0]) ^^ 2 + (p1[1] - p2[1]) ^^ 2) ^^ 0.5;
}

void main() {
    immutable x1 = I(100, 1.1);
    immutable x2 = I(200, 2.2);
    immutable y1 = I( 50, 1.2);
    immutable y2 = I(100, 2.3);

    immutable p1 = tuple(x1, y1);
    immutable p2 = tuple(x2, y2);
    writefln("Point p1: (%s, %s)", p1[0], p1[1]);
    writefln("Point p2: (%s, %s)", p2[0], p2[1]);
    writeln("Distance(p1, p2): ", distance(p1, p2));
}


let sqr (x : float) = x * x
let abs (x : float)  = System.Math.Abs x
let pow = System.Math.Pow

type Approx (value : float, sigma : float) =
    member this.value = value
    member this.sigma = sigma

    static member (~-) (x : Approx) = Approx (- x.value, x.sigma)
    static member (%+) (x: Approx, y : float) = Approx (x.value + y, x.sigma)
    static member (%+) (y : float, x : Approx) = x %+ y
    static member (%+) (x : Approx, y : Approx) =
        Approx (x.value + y.value, sqrt((sqr x.sigma)+(sqr y.sigma)))
    static member (%-) (x: Approx, y : float) = Approx (x.value - y, x.sigma)
    static member (%-) (y : float, x : Approx) = (-x) %+ y
    static member (%-) (x : Approx, y : Approx) = x %+ (-y)
    static member (%*) (x : Approx, y : float) = Approx (y * x.value, abs(y * x.sigma))
    static member (%*) (y : float, x : Approx) = x %* y
    static member (%*) (x : Approx, y : Approx) =
        let v = x.value * y.value
        Approx (v, v * sqrt(sqr(x.sigma/x.value))+sqr(y.sigma/y.value))
    static member (%/) (x : Approx, y : Approx) =
        Approx (x.value / y.value, sqrt(sqr(x.sigma/x.value))+sqr(y.sigma/y.value))
    static member (%^) (x : Approx, y : float) =
        if y < 0. then failwith ("Cannot raise the power with a negative number " + y.ToString())
        let v = pow(x.value,y)
        Approx (v, abs(v * y * x.sigma / x.value))

    override this.ToString() = sprintf "%.2f ±%.2f" value sigma

[<EntryPoint>]
let main argv =
    let x1 = Approx (100., 1.1)
    let y1 = Approx (50., 1.2)
    let x2 = Approx (200., 2.2)
    let y2 = Approx (100., 2.3)

    printfn "Distance: %A" ((((x1 %- x2) %^ 2.) %+ ((y1 %- y2) %^ 2.)) %^ 0.5)
    0


USING: accessors arrays fry kernel locals math math.functions
multi-methods parser prettyprint prettyprint.custom sequences ;
RENAME: GENERIC: multi-methods => MM-GENERIC:
FROM: syntax => M: ;
IN: imprecise

TUPLE: imprecise
    { value float read-only }
    { sigma float read-only } ;

C: <imprecise> imprecise

: >imprecise< ( imprecise -- value sigma )
    [ value>> ] [ sigma>> ] bi ;

! Define a custom syntax for imprecise numbers.

<< SYNTAX: I{ \ } [ first2 <imprecise> ] parse-literal ; >>
M: imprecise pprint-delims drop \ I{ \ } ;
M: imprecise >pprint-sequence >imprecise< 2array ;
M: imprecise pprint* pprint-object ;

<PRIVATE

! Error functions

: f+-i ( float imprecise quot -- imprecise )
    [ >imprecise< ] dip dip <imprecise> ; inline

: i+-i ( imprecise1 imprecise2 quot -- imprecise )
    '[ [ value>> ] [email protected] @ ]
    [ [ sigma>> sq ] [email protected] + sqrt <imprecise> ] 2bi ; inline

: f*/i ( float imprecise quot -- imprecise )
    [ >imprecise< overd ] dip [ * abs ] 2bi* <imprecise> ;
    inline

:: i*/i ( a b quot -- imprecise )
    a b [ >imprecise< ] [email protected] :> ( vala siga valb sigb )
    vala valb quot call :> val
    val sq siga sq * vala sq /f sigb sq + valb sq /f sqrt :> sig
    val sig <imprecise> ; inline

PRIVATE>

MM-GENERIC: ~+ ( obj1 obj2 -- imprecise ) foldable flushable
METHOD: ~+ { float imprecise } [ + ] f+-i ;
METHOD: ~+ { imprecise float } swap ~+ ;
METHOD: ~+ { imprecise imprecise } [ + ] i+-i ;

MM-GENERIC: ~- ( obj1 obj2 -- imprecise ) foldable flushable
METHOD: ~- { float imprecise } [ - ] f+-i ;
METHOD: ~- { imprecise float } swap [ swap - ] f+-i ;
METHOD: ~- { imprecise imprecise } [ - ] i+-i ;

MM-GENERIC: ~* ( obj1 obj2 -- imprecise ) foldable flushable
METHOD: ~* { float imprecise } [ * ] f*/i ;
METHOD: ~* { imprecise float } swap ~* ;
METHOD: ~* { imprecise imprecise } [ * ] i*/i ;

MM-GENERIC: ~/ ( obj1 obj2 -- imprecise ) foldable flushable
METHOD: ~/ { float imprecise } [ /f ] f*/i ;
METHOD: ~/ { imprecise float } swap [ swap /f ] f*/i ;
METHOD: ~/ { imprecise imprecise } [ /f ] i*/i ;

:: ~^ ( a x -- imprecise )
    a >imprecise< :> ( vala siga )
    vala x ^ >rect drop :> val
    val x * siga vala /f * abs :> sig
    val sig <imprecise> ; foldable flushable

<PRIVATE

: imprecise-demo ( -- )
    I{ 100 1.1 } I{ 200 2.2 } ~- 2. ~^
    I{ 50 1.2 } I{ 100 2.3 } ~- 2. ~^ ~+ 0.5 ~^ . ;

PRIVATE>

MAIN: imprecise-demo


      PROGRAM CALCULATE	!A distance, with error propagation.
      REAL X1, Y1, X2, Y2	!The co-ordinates.
      REAL X1E,Y1E,X2E,Y2E	!Their standard deviation.
      DATA X1, Y1 ,X2, Y2 /100., 50., 200.,100./	!Specified
      DATA X1E,Y1E,X2E,Y2E/  1.1, 1.2,  2.2, 2.3/	!Values.
      REAL DX,DY,D2,D,DXE,DYE,E	!Assistants.
      CHARACTER*1 C			!I'm stuck with code page 437 instead of 850.
      PARAMETER (C = CHAR(241))		!Thus ± does not yield this glyph on a "console" screen. CHAR(241) does.
      REAL SD	!This is an arithmetic statement function.
      SD(X,P,S) = P*ABS(X)**(P - 1)*S	!SD for X**P where SD of X is S
      WRITE (6,1) X1,C,X1E,Y1,C,Y1E,	!Reveal the points
     1            X2,C,X2E,Y2,C,Y2E	!Though one could have used an array...
    1 FORMAT ("Euclidean distance between two points:"/	!A heading.
     1 ("(",F5.1,A1,F3.1,",",F5.1,A1,F3.1,")"))		!Thus, One point per line.
      DX = (X1 - X2)			!X difference.
      DXE = SQRT(X1E**2 + X2E**2)	!SD for DX, a simple difference.
      DY = (Y1 - Y2)			!Y difference.
      DYE = SQRT(Y1E**2 + Y2E**2)	!SD for DY, (Y1 - Y2)
      D2 = DX**2 + DY**2		!The distance, squared.
      DXE = SD(DX,2,DXE)		!SD for DX**2
      DYE = SD(DY,2,DYE)		!SD for DY**2
      E = SQRT(DXE**2 + DYE**2)		!SD for their sum
      D = SQRT(D2)			!The distance!
      E = SD(D2,0.5,E)			!SD after the SQRT.
      WRITE (6,2) D,C,E			!Ahh, the relief.
    2 FORMAT ("Distance",F6.1,A1,F4.2)	!Sizes to fit the example.
      END	!Enough.


'----------------------
' definition of a "measurement" type with value and uncartainty
' and operators that can operate on them
'---------------------

#macro p2(x)
    (x)*(x)
#endmacro

type meas
    vlu as double
    unc as double
end type

operator + ( a as meas, b as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu + b.vlu
    ret.unc = sqr( a.unc*a.unc + b.unc*b.unc )
    return ret
end operator

operator + ( c as double, a as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu + c
    ret.unc = a.unc
    return ret
end operator

operator + ( a as meas, c as double ) as meas
    return c+a
end operator

operator - ( a as meas, b as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu - b.vlu
    ret.unc = sqr( a.unc*a.unc + b.unc*b.unc )
    return ret
end operator

operator - ( c as double, a as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu - c
    ret.unc = a.unc
    return ret
end operator

operator - ( a as meas, c as double ) as meas
    dim ret as meas
    ret.vlu = c - a.vlu
    ret.unc = a.unc
    return ret
end operator

operator * ( a as meas, b as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu*b.vlu
    ret.unc = sqr(p2(ret.vlu) * (p2(a.unc/a.vlu)+p2(b.unc/b.vlu)))
    return ret
end operator

operator * ( c as double, a as meas ) as meas
    dim ret as meas
    ret.vlu = a.vlu*c
    ret.unc = abs(c*a.unc)
    return ret
end operator

operator * ( a as meas, c as double ) as meas
    return c*a
end operator

operator ^ ( a as meas, c as double ) as meas
    dim ret as meas
    ret.vlu = a.vlu ^ c
    ret.unc = abs(ret.vlu*c*a.unc/a.vlu)
    return ret
end operator

operator / ( c as double, a as meas ) as meas
    return c*a^(-1)
end operator

operator / ( a as meas, c as double ) as meas
    return a*(1.0/c)
end operator

operator / ( a as meas, b as meas ) as meas
    return b*a^(-1)
end operator

sub printm( a as meas )
    print using "####.##### +- ####.####"; a.vlu; a.unc
end sub

'--------------------------------
'   now the results
'--------------------------------

dim as meas x1, y1, x2, y2
x1.vlu = 100.
x1.unc = 1.1
y1.vlu = 50.
y1.unc = 1.2
x2.vlu = 200.
x2.unc = 2.2
y2.vlu = 100.
y2.unc = 2.3

printm( ((x1-x2)^2 + (y1-y2)^2)^0.5 )


package main

import (
    "fmt"
    "math"
)

// "uncertain number type"
// a little optimization is to represent the error term with its square.
// this saves some taking of square roots in various places.
type unc struct {
    n float64 // the number
    s float64 // *square* of one sigma error term
}

// constructor, nice to have so it can handle squaring of error term
func newUnc(n, s float64) *unc {
    return &unc{n, s * s}
}

// error term accessor method, nice to have so it can handle recovering
// (non-squared) error term from internal (squared) representation
func (z *unc) errorTerm() float64 {
    return math.Sqrt(z.s)
}

// Arithmetic methods are modeled on the Go big number package.
// The basic scheme is to pass all operands as method arguments, compute
// the result into the method receiver, and then return the receiver as
// the result of the method.  This has an advantage of letting the programer
// determine allocation and use of temporary objects, reducing garbage;
// and has the convenience and efficiency of allowing operations to be chained.

// addition/subtraction
func (z *unc) addC(a *unc, c float64) *unc {
    *z = *a
    z.n += c
    return z
}

func (z *unc) subC(a *unc, c float64) *unc {
    *z = *a
    z.n -= c
    return z
}

func (z *unc) addU(a, b *unc) *unc {
    z.n = a.n + b.n
    z.s = a.s + b.s
    return z
}
func (z *unc) subU(a, b *unc) *unc {
    z.n = a.n - b.n
    z.s = a.s + b.s
    return z
}

// multiplication/division
func (z *unc) mulC(a *unc, c float64) *unc {
    z.n = a.n * c
    z.s = a.s * c * c
    return z
}

func (z *unc) divC(a *unc, c float64) *unc {
    z.n = a.n / c
    z.s = a.s / (c * c)
    return z
}

func (z *unc) mulU(a, b *unc) *unc {
    prod := a.n * b.n
    z.n, z.s = prod, prod*prod*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}

func (z *unc) divU(a, b *unc) *unc {
    quot := a.n / b.n
    z.n, z.s = quot, quot*quot*(a.s/(a.n*a.n)+b.s/(b.n*b.n))
    return z
}

// exponentiation
func (z *unc) expC(a *unc, c float64) *unc {
    f := math.Pow(a.n, c)
    g := f * c / a.n
    z.n = f
    z.s = a.s * g * g
    return z
}

func main() {
    x1 := newUnc(100, 1.1)
    x2 := newUnc(200, 2.2)
    y1 := newUnc(50, 1.2)
    y2 := newUnc(100, 2.3)
    var d, d2 unc
    d.expC(d.addU(d.expC(d.subU(x1, x2), 2), d2.expC(d2.subU(y1, y2), 2)), .5)
    fmt.Println("d:    ", d.n)
    fmt.Println("error:", d.errorTerm())
}


data Error a = Error {value :: a, uncertainty :: a} deriving (Eq, Show)

instance (Floating a) => Num (Error a) where
	Error a ua + Error b ub = Error (a + b) (sqrt (ua ^ 2 + ub ^ 2))
	negate (Error a ua) = Error (negate a) ua
	Error a ua * Error b ub = Error (a * b) (abs (a * b * sqrt ((ua / a) ^ 2 + (ub / b) ^ 2))) -- I've factored out the f^2 from the square root
	fromInteger a = Error (fromInteger a) 0

instance (Floating a) => Fractional (Error a) where
	fromRational a = Error (fromRational a) 0
	Error a ua / Error b ub = Error (a / b) (abs (a / b * sqrt ((ua / a) ^ 2 + (ub / b) ^ 2))) -- I've factored out the f^2 from the square root

instance (Floating a) => Floating (Error a) where
	Error a ua ** Error c 0 = Error (a ** c) (abs (ua * c * a**c / a))

main = print (sqrt ((x1 - x2) ** 2 + (y1 - y2) ** 2)) where -- using (^) for exponentiation would calculate a*a, which the problem specifically said was calculated wrong
	x1 = Error 100 1.1
	y1 = Error 50 1.2
	x2 = Error 200 2.2
	y2 = Error 100 2.3


record num(val,err)

procedure main(a)
    x1 := num(100.0, 1.1)
    y1 := num(50.0,  1.2)
    x2 := num(200.0, 2.2)
    y2 := num(100.0, 2.3)
    d := pow(add(pow(sub(x1,x2),2),pow(sub(y1,y2),2)),0.5)
    write("d = [",d.val,", ",d.err,"]")
end

procedure add(a,b)
    return (numeric(a)+numeric(b)) |
           num(numeric(a)+b.val, b.err) |
           num(a.val+numeric(b), a.err) |
           num(a.val+b.val, (a.err^2 + b.err^2) ^ 0.5)
end

procedure sub(a,b)
    return (numeric(a)-numeric(b)) |
           num(numeric(a)-b.val, b.err) |
           num(a.val-numeric(b), a.err) |
           num(a.val-b.val, (a.err^2 + b.err^2) ^ 0.5)
end

procedure mul(a,b)
    return (numeric(a)*numeric(b)) |
           num(numeric(a)*b.val, abs(a*b.err)) |
           num(a.val*numeric(b), abs(b*a.err)) |
           num(f := a.val*b.val, ((f^2*((a.err/a.val)^2+(b.err/b.val)^2))^0.5))
end

procedure div(a,b)
    return (numeric(a)/numeric(b)) |
           num(numeric(a)/b.val, abs(a*b.err)) |
           num(a.val/numeric(b), abs(b*a.err)) |
           num(f := a.val/b.val, ((f^2*((a.err/a.val)^2+(b.err/b.val)^2))^0.5))
end

procedure pow(a,b)
    return (numeric(a)^numeric(b)) |
           num(f := a.val^numeric(b), abs(f*b*(a.err/a.val)))
end


public class Approx {
    private double value;
    private double error;

    public Approx(){this.value = this.error = 0;}

    public Approx(Approx b){
        this.value = b.value;
        this.error = b.error;
    }

    public Approx(double value, double error){
        this.value = value;
        this.error = error;
    }

    public Approx add(Approx b){
        value+= b.value;
        error = Math.sqrt(error * error + b.error * b.error);
        return this;
    }

    public Approx add(double b){
        value+= b;
        return this;
    }

    public Approx sub(Approx b){
        value-= b.value;
        error = Math.sqrt(error * error + b.error * b.error);
        return this;
    }

    public Approx sub(double b){
        value-= b;
        return this;
    }

    public Approx mult(Approx b){
        double oldVal = value;
        value*= b.value;
        error = Math.sqrt(value * value * (error*error) / (oldVal*oldVal) +
                                  (b.error*b.error) / (b.value*b.value));
        return this;
    }

    public Approx mult(double b){
        value*= b;
        error = Math.abs(b * error);
        return this;
    }

    public Approx div(Approx b){
        double oldVal = value;
        value/= b.value;
        error = Math.sqrt(value * value * (error*error) / (oldVal*oldVal) +
                                  (b.error*b.error) / (b.value*b.value));
        return this;
    }

    public Approx div(double b){
        value/= b;
        error = Math.abs(b * error);
        return this;
    }

    public Approx pow(double b){
        double oldVal = value;
        value = Math.pow(value, b);
        error = Math.abs(value * b * (error / oldVal));
        return this;
    }

    @Override
    public String toString(){return value+"±"+error;}

    public static void main(String[] args){
        Approx x1 = new Approx(100, 1.1);
        Approx y1 = new Approx(50, 1.2);
        Approx x2 = new Approx(200, 2.2);
        Approx y2 = new Approx(100, 2.3);

        x1.sub(x2).pow(2).add(y1.sub(y2).pow(2)).pow(0.5);

        System.out.println(x1);
    }
}


using Measurements

x1 = measurement(100, 1.1)
x2 = measurement(200, 2.2)
y1 = measurement(50, 1.2)
y2 = measurement(100, 2.3)

d = sqrt((x1 - x2)^2 + (y1 - y2)^2)

@show d
@show d.val, d.err


import java.lang.Math.*

data class Approx(val ν: Double, val σ: Double = 0.0) {
    constructor(a: Approx) : this(a.ν, a.σ)
    constructor(n: Number) : this(n.toDouble(), 0.0)

    override fun toString() = "$ν ±$σ"

    operator infix fun plus(a: Approx) = Approx(ν + a.ν, sqrt(σ * σ + a.σ * a.σ))
    operator infix fun plus(d: Double) = Approx(ν + d, σ)
    operator infix fun minus(a: Approx) = Approx(ν - a.ν, sqrt(σ * σ + a.σ * a.σ))
    operator infix fun minus(d: Double) = Approx(ν - d, σ)

    operator infix fun times(a: Approx): Approx {
        val v = ν * a.ν
        return Approx(v, sqrt(v * v * σ * σ / (ν * ν) + a.σ * a.σ / (a.ν * a.ν)))
    }

    operator infix fun times(d: Double) = Approx(ν * d, abs(d * σ))

    operator infix fun div(a: Approx): Approx {
        val v = ν / a.ν
        return Approx(v, sqrt(v * v * σ * σ / (ν * ν) + a.σ * a.σ / (a.ν * a.ν)))
    }

    operator infix fun div(d: Double) = Approx(ν / d, abs(d * σ))

    fun pow(d: Double): Approx {
        val v = pow(ν, d)
        return Approx(v, abs(v * d * σ / ν))
    }
}

fun main(args: Array<String>) {
    val x1 = Approx(100.0, 1.1)
    val y1 = Approx(50.0, 1.2)
    val x2 = Approx(200.0, 2.2)
    val y2 = Approx(100.0, 2.3)
    println(((x1 - x2).pow(2.0) + (y1 - y2).pow(2.0)).pow(0.5))
}


PlusMinus /: a_ ± σa_ + c_?NumericQ := N[(a + c) ± σa];
PlusMinus /: a_ ± σa_ + b_ ± σb_ := N[(a + b) ± [email protected]{σa, σb}];
PlusMinus /: c_?NumericQ (a_ ± σa_) := N[c a ± Abs[c σa]];
PlusMinus /: (a_ ± σa_) (b_ ± σb_) := N[a b ± (a b [email protected]{σa/a, σb/b})^2];
PlusMinus /: (a_ ± σa_)^c_?NumericQ := N[a^c ± Abs[a^c σa/a]];


import strformat
import math

type
  Imprecise = object
    x: float
    σ: float

template `^`(a, b: float): float =
  pow(a, b)
template `-`(a: Imprecise): Imprecise =
  Imprecise(x: -a.x, σ: a.σ)
template `+`(a, b: Imprecise): Imprecise =
  Imprecise(x: a.x + b.x, σ: sqrt(a.σ ^ 2 + b.σ ^ 2))
template `-`(a, b: Imprecise): Imprecise =
  Imprecise(x: a.x - b.x, σ: sqrt(a.σ ^ 2 + b.σ ^ 2))
template `*`(a, b: Imprecise): Imprecise =
  let x = a.x * b.x
  let σ = sqrt(x ^ 2 * ((a.σ / a.x) ^ 2 + (b.σ / b.x) ^ 2))
  Imprecise(x: x, σ: σ)
template `/`(a, b: Imprecise): Imprecise =
  let x = a.x / b.x
  let σ = sqrt(x ^ 2 * ((a.σ / a.x) ^ 2 + (b.σ / b.x) ^ 2))
  Imprecise(x: x, σ: σ)
template `^`(a: Imprecise, b: float): Imprecise =
  if b < 0:
    raise newException(IOError, "Cannot raise to negative power.")
  let x = a.x ^ b
  let σ = abs(x * b * a.σ / a.x)
  Imprecise(x: x, σ: σ)
template sqrt(a: Imprecise): Imprecise =
  a ^ 0.5

proc `$`(a: Imprecise): string =
  fmt"{a.x:.2f} ± {a.σ:.2f}"

var x1 = Imprecise(x: 100, σ: 1.1)
var y1 = Imprecise(x: 50, σ: 1.2)
var x2 = Imprecise(x: 200, σ: 2.2)
var y2 = Imprecise(x: 100, σ: 2.3)

echo sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2)


use utf8;
package ErrVar;
use strict;

# helper function, apply f to pairs (a, b) from listX and listY
sub zip(&$$) {
	my ($f, $x, $y) = @_;
	my $l = $#$x;
	if ($l < $#$y) { $l = $#$y };

	my @out;
	for (0 .. $l) {
		local $a = $x->[$_];
		local $b = $y->[$_];
		push @out, $f->();
	}
	\@out
}

use overload
	'""'	=> \&_str,
	'+'	=> \&_add,
	'-'	=> \&_sub,
	'*'	=> \&_mul,
	'/'	=> \&_div,
	'bool'	=> \&_bool,
	'<=>'	=> \&_ncmp,
	'neg'	=> \&_neg,

	'sqrt'	=> \&_sqrt,
	'log'	=> \&_log,
	'exp'	=> \&_exp,
	'**'	=> \&_pow,
;

# make a variable with mean value and a list of coefficient to
# variables providing independent errors
sub make {
	my $x = shift;
	bless [$x, [@{+shift}]]
}

sub _str { sprintf "%g±%.3g", $_[0][0], sigma($_[0]) }

# mean value of the var, or just the input if it's not of this class
sub mean {
	my $x = shift;
	ref($x) && $x->isa(__PACKAGE__) ? $x->[0] : $x
}

# return variance index array
sub vlist {
	my $x = shift;
	ref($x) && $x->isa(__PACKAGE__) ? $x->[1] : [];
}

sub variance {
	my $x = shift;
	return 0 unless ref($x) and $x->isa(__PACKAGE__);
	my $s;
	$s += $_ * $_ for (@{$x->[1]});
	$s
}

sub covariance {
	my ($x, $y) = @_;
	return 0 unless ref($x) && $x->isa(__PACKAGE__);
	return 0 unless ref($y) && $y->isa(__PACKAGE__);

	my $s;
	zip { $s += $a * $b } vlist($x), vlist($y);
	$s
}

sub sigma { sqrt variance(shift) }

# to determine if a var is probably zero. we use 1σ here
sub _bool {
	my $x = shift;
	return abs(mean($x)) > sigma($x);
}

sub _ncmp {
	my $x = shift() - shift()	or return 0;
	return mean($x) > 0 ? 1 : -1;
}

sub _neg {
	my $x = shift;
	bless [ -mean($x), [map(-$_, @{vlist($x)}) ] ];
}

sub _add {
	my ($x, $y) = @_;
	my ($x0, $y0) = (mean($x), mean($y));
	my ($xv, $yv) = (vlist($x), vlist($y));
	bless [$x0 + $y0, zip {$a + $b} $xv, $yv];
}

sub _sub {
	my ($x, $y, $swap) = @_;
	if ($swap) { ($x, $y) = ($y, $x) }
	my ($x0, $y0) = (mean($x), mean($y));
	my ($xv, $yv) = (vlist($x), vlist($y));
	bless [$x0 - $y0, zip {$a - $b} $xv, $yv];
}

sub _mul {
	my ($x, $y) = @_;
	my ($x0, $y0) = (mean($x), mean($y));
	my ($xv, $yv) = (vlist($x), vlist($y));

	$xv = [ map($y0 * $_, @$xv) ];
	$yv = [ map($x0 * $_, @$yv) ];

	bless [$x0 * $y0, zip {$a + $b} $xv, $yv];
}

sub _div {
	my ($x, $y, $swap) = @_;
	if ($swap) { ($x, $y) = ($y, $x) }

	my ($x0, $y0) = (mean($x), mean($y));
	my ($xv, $yv) = (vlist($x), vlist($y));

	$xv = [ map($_/$y0, @$xv) ];
	$yv = [ map($x0 * $_/$y0/$y0, @$yv) ];

	bless [$x0 / $y0, zip {$a + $b} $xv, $yv];
}

sub _sqrt {
	my $x = shift;
	my $x0 = mean($x);
	my $xv = vlist($x);
	$x0 = sqrt($x0);
	$xv = [ map($_ / 2 / $x0, @$xv) ];
	bless [$x0, $xv]
}

sub _pow {
	my ($x, $y, $swap) = @_;
	if ($swap) { ($x, $y) = ($y, $x) }
	if ($x < 0) {
		if (int($y) != $y || ($y & 1)) {
			die "Can't take pow of negative number $x";
		}
		$x = -$x;
	}
	exp($y * log $x)
}

sub _exp {
	my $x = shift;
	my $x0 = exp(mean($x));
	my $xv = vlist($x);
	bless [ $x0, [map($x0 * $_, @$xv) ] ]
}

sub _log {
	my $x = shift;
	my $x0 = mean($x);
	my $xv = vlist($x);
	bless [ log($x0), [ map($_ / $x0, @$xv) ] ]
}

"If this package were to be in its own file, you need some truth value to end it like this.";

package main;

sub e { ErrVar::make @_ };

# x1 is of mean value 100, containing error 1.1 from source 1, etc.
# all error sources are independent.
my $x1 = e 100, [1.1, 0,   0,   0  ];
my $x2 = e 200, [0,   2.2, 0,   0  ];
my $y1 = e 50,  [0,   0,   1.2, 0  ];
my $y2 = e 100, [0,   0,   0,   2.3];

my $z1 = sqrt(($x1 - $x2) ** 2 + ($y1 - $y2) ** 2);
print "distance: $z1\n\n";

# this is not for task requirement
my $a = $x1 + $x2;
my $b = $y1 - 2 * $x2;
print "covariance between $a and $b: ", $a->covariance($b), "\n";


// Non-transitive dice. Nigel Galloway: August 9th., 2020
let die=[for n0 in [1..4] do for n1 in [n0..4] do for n2 in [n1..4] do for n3 in [n2..4]->[n0;n1;n2;n3]]
let N=seq{for n in die->(n,[for g in die do if (seq{for n in n do for g in g->compare n g}|>Seq.sum<0) then yield g])}|>Map.ofSeq
let n3=seq{for d1 in die do for d2 in N.[d1] do for d3 in N.[d2] do if List.contains d1 N.[d3] then yield (d1,d2,d3)}
let n4=seq{for d1 in die do for d2 in N.[d1] do for d3 in N.[d2] do for d4 in N.[d3] do if List.contains d1 N.[d4] then yield (d1,d2,d3,d4)}
n3|>Seq.iter(fun(d1,d2,d3)->printfn "%A<%A; %A<%A; %A>%A\n" d1 d2 d2 d3 d1 d3)
n4|>Seq.iter(fun(d1,d2,d3,d4)->printfn "%A<%A; %A<%A; %A<%A; %A>%A" d1 d2 d2 d3 d3 d4 d1 d4)


with javascript_semantics
enum VALUE, DELTA

type imprecise(object imp)
    return sequence(imp) and atom(imp[VALUE]) and atom(imp[DELTA])
end type

function sqr(atom a)
    return a*a
end function

function imprecise_add(imprecise a, b)
    atom delta = sqrt(sqr(a[DELTA]) + sqr(b[DELTA]))
    imprecise ret = {a[VALUE] + b[VALUE], delta}
    return ret
end function

function imprecise_mul(imprecise a, b)
    atom delta = sqrt(sqr(a[VALUE]*b[DELTA]) + sqr(b[VALUE]*a[DELTA]))
    imprecise ret = {a[VALUE] * b[VALUE],delta}
    return ret
end function

function imprecise_div(imprecise a, b)
    atom delta = sqrt(sqr(a[VALUE]*b[DELTA]) + sqr(b[VALUE]*a[DELTA]))/sqr(b[VALUE])
    imprecise ret = {a[VALUE] / b[VALUE], delta}
    return ret
end function

function imprecise_pow(imprecise a, atom c)
    atom v = power(a[VALUE], c),
         delta = abs(v*c*a[DELTA]/a[VALUE])
    imprecise ret = {v,delta}
    return ret
end function

function printImprecise(imprecise imp)
    return sprintf("%g+/-%g",imp)
end function

imprecise x1 = {100, 1.1},
          y1 = {50, 1.2},
          x2 = {-200, 2.2},
          y2 = {-100, 2.3},
          tmp1, tmp2,
          d

    tmp1 = imprecise_add(x1, x2)
    tmp1 = imprecise_pow(tmp1, 2)
    tmp2 = imprecise_add(y1, y2)
    tmp2 = imprecise_pow(tmp2, 2)
    d = imprecise_add(tmp1,tmp2)
    d = imprecise_pow(d, 0.5)
    printf(1,"Distance, d, between the following points :")
    printf(1,"\n( x1, y1) = ( %s, %s)",{printImprecise(x1),printImprecise(y1)})
    printf(1,"\n( x2, y2) = ( %s, %s)",{printImprecise(x2),printImprecise(y2)})
    printf(1,"\nis d = %s\n", {printImprecise(d)})


USING: grouping io kernel math math.combinatorics math.ranges
prettyprint sequences ;

: possible-dice ( n -- seq )
    [ [1,b] ] [ selections ] bi [ [ <= ] monotonic? ] filter ;

: cmp ( seq seq -- n ) [ - sgn ] cartesian-map concat sum ;

: non-transitive? ( seq -- ? )
   [ 2 clump [ first2 cmp neg? ] all? ]
   [ [ last ] [ first ] bi cmp neg? and ] bi ;

: find-non-transitive ( #sides #dice -- seq )
    [ possible-dice ] [ <k-permutations> ] bi*
    [ non-transitive? ] filter ;

! Task
"Number of eligible 4-sided dice: " write
4 possible-dice length . nl

"All ordered lists of 3 non-transitive dice with 4 sides:" print
4 3 find-non-transitive . nl

"All ordered lists of 4 non-transitive dice with 4 sides:" print
4 4 find-non-transitive .


package main

import (
    "fmt"
    "sort"
)

func fourFaceCombs() (res [][4]int) {
    found := make([]bool, 256)
    for i := 1; i <= 4; i++ {
        for j := 1; j <= 4; j++ {
            for k := 1; k <= 4; k++ {
                for l := 1; l <= 4; l++ {
                    c := [4]int{i, j, k, l}
                    sort.Ints(c[:])
                    key := 64*(c[0]-1) + 16*(c[1]-1) + 4*(c[2]-1) + (c[3] - 1)
                    if !found[key] {
                        found[key] = true
                        res = append(res, c)
                    }
                }
            }
        }
    }
    return
}

func cmp(x, y [4]int) int {
    xw := 0
    yw := 0
    for i := 0; i < 4; i++ {
        for j := 0; j < 4; j++ {
            if x[i] > y[j] {
                xw++
            } else if y[j] > x[i] {
                yw++
            }
        }
    }
    if xw < yw {
        return -1
    } else if xw > yw {
        return 1
    }
    return 0
}

func findIntransitive3(cs [][4]int) (res [][3][4]int) {
    var c = len(cs)
    for i := 0; i < c; i++ {
        for j := 0; j < c; j++ {
            for k := 0; k < c; k++ {
                first := cmp(cs[i], cs[j])
                if first == -1 {
                    second := cmp(cs[j], cs[k])
                    if second == -1 {
                        third := cmp(cs[i], cs[k])
                        if third == 1 {
                            res = append(res, [3][4]int{cs[i], cs[j], cs[k]})
                        }
                    }
                }
            }
        }
    }
    return
}

func findIntransitive4(cs [][4]int) (res [][4][4]int) {
    c := len(cs)
    for i := 0; i < c; i++ {
        for j := 0; j < c; j++ {
            for k := 0; k < c; k++ {
                for l := 0; l < c; l++ {
                    first := cmp(cs[i], cs[j])
                    if first == -1 {
                        second := cmp(cs[j], cs[k])
                        if second == -1 {
                            third := cmp(cs[k], cs[l])
                            if third == -1 {
                                fourth := cmp(cs[i], cs[l])
                                if fourth == 1 {
                                    res = append(res, [4][4]int{cs[i], cs[j], cs[k], cs[l]})
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return
}

func main() {
    combs := fourFaceCombs()
    fmt.Println("Number of eligible 4-faced dice", len(combs))
    it3 := findIntransitive3(combs)
    fmt.Printf("\n%d ordered lists of 3 non-transitive dice found, namely:\n", len(it3))
    for _, a := range it3 {
        fmt.Println(a)
    }
    it4 := findIntransitive4(combs)
    fmt.Printf("\n%d ordered lists of 4 non-transitive dice found, namely:\n", len(it4))
    for _, a := range it4 {
        fmt.Println(a)
    }
}


(scl 12)
(load "@lib/math.l")

# Overload arithmetic operators +, -, *, / and **
(redef + @
   (let R (next)
      (while (args)
         (let N (next)
            (setq R
               (if2 (atom R) (atom N)
                  (+ R N)                       # c + c
                  (cons (+ R (car N)) (cdr N))  # c + a
                  (cons (+ (car R) N) (cdr R))  # a + c
                  (cons                         # a + b
                     (+ (car R) (car N))
                     (+ (cdr R) (cdr N)) ) ) ) ) )
      R ) )

(redef - @
   (let R (next)
      (ifn (args)
         (- R)
         (while (args)
            (let N (next)
               (setq R
                  (if2 (atom R) (atom N)
                     (- R N)                       # c - c
                     (cons (- R (car N)) (cdr N))  # c - a
                     (cons (- (car R) N) (cdr R))  # a - c
                     (cons                         # a - b
                        (- (car R) (car N))
                        (+ (cdr R) (cdr N)) ) ) ) ) )
         R ) ) )

(redef * @
   (let R (next)
      (while (args)
         (let N (next)
            (setq R
               (if2 (atom R) (atom N)
                  (* R N)                                        # c * c
                  (cons                                          # c * a
                     (*/ R (car N) 1.0)
                     (mul2div2 (cdr N) R 1.0) )
                  (cons                                          # a * c
                     (*/ (car R) N 1.0)
                     (mul2div2 (cdr R) N 1.0) )
                  (uncMul (*/ (car R) (car N) 1.0) R N) ) ) ) )  # a * b
      R ) )

(redef / @
   (let R (next)
      (while (args)
         (let N (next)
            (setq R
               (if2 (atom R) (atom N)
                  (/ R N)                                        # c / c
                  (cons                                          # c / a
                     (*/ R 1.0 (car N))
                     (mul2div2 (cdr N) R 1.0) )
                  (cons                                          # a / c
                     (*/ (car R) 1.0 N)
                     (mul2div2 (cdr R) N 1.0) )
                  (uncMul (*/ (car R) 1.0 (car N)) R N) ) ) ) )  # a / b
      R ) )

(redef ** (A C)
   (if (atom A)
      (** A C)
      (let F (pow (car A) C)
         (cons F
            (mul2div2 (cdr A) (*/ F C (car A)) 1.0) ) ) ) )

# Utilities
(de mul2div2 (A B C)
   (*/ A B B (* C C)) )

(de uncMul (F R N)
   (cons F
      (mul2div2
         (+
            (mul2div2 (cdr R) 1.0 (car R))
            (mul2div2 (cdr N) 1.0 (car N)) )
         F
         1.0 ) ) )

# I/O conversion
(de unc (N U)
   (if U
      (cons N (*/ U U 1.0))
      (pack
         (round (car N) 10)
         " ± "
         (round (sqrt (cdr N) 1.0) 8) ) ) )


from collections import namedtuple
import math

class I(namedtuple('Imprecise', 'value, delta')):
    'Imprecise type: I(value=0.0, delta=0.0)'

    __slots__ = ()

    def __new__(_cls, value=0.0, delta=0.0):
        'Defaults to 0.0 ± delta'
        return super().__new__(_cls, float(value), abs(float(delta)))

    def reciprocal(self):
        return I(1. / self.value, self.delta / (self.value**2))

    def __str__(self):
        'Shorter form of Imprecise as string'
        return 'I(%g, %g)' % self

    def __neg__(self):
        return I(-self.value, self.delta)

    def __add__(self, other):
        if type(other) == I:
            return I( self.value + other.value, (self.delta**2 + other.delta**2)**0.5 )
        try:
            c = float(other)
        except:
            return NotImplemented
        return I(self.value + c, self.delta)

    def __sub__(self, other):
        return self + (-other)

    def __radd__(self, other):
        return I.__add__(self, other)

    def __mul__(self, other):
        if type(other) == I:
            #if id(self) == id(other):
            #    return self ** 2
            a1,b1 = self
            a2,b2 = other
            f = a1 * a2
            return I( f, f * ( (b1 / a1)**2 + (b2 / a2)**2 )**0.5 )
        try:
            c = float(other)
        except:
            return NotImplemented
        return I(self.value * c, self.delta * c)

    def __pow__(self, other):
        if type(other) == I:
            return NotImplemented
        try:
            c = float(other)
        except:
            return NotImplemented
        f = self.value ** c
        return I(f, f * c * (self.delta / self.value))

    def __rmul__(self, other):
        return I.__mul__(self, other)

    def __truediv__(self, other):
        if type(other) == I:
            return self.__mul__(other.reciprocal())
        try:
            c = float(other)
        except:
            return NotImplemented
        return I(self.value / c, self.delta / c)

    def __rtruediv__(self, other):
        return other * self.reciprocal()

    __div__, __rdiv__ = __truediv__, __rtruediv__

Imprecise = I

def distance(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    return ((x1 - x2)**2 + (y1 - y2)**2)**0.5

x1 = I(100, 1.1)
x2 = I(200, 2.2)
y1 = I( 50, 1.2)
y2 = I(100, 2.3)

p1, p2 = (x1, y1), (x2, y2)
print("Distance between points\n  p1: %s\n  and p2: %s\n  = %r" % (
      p1, p2, distance(p1, p2)))


{-# language LambdaCase #-}
import Data.List
import Control.Monad

newtype Dice = Dice [Int]

instance Show Dice where
  show (Dice s) = "(" ++ unwords (show <$> s) ++ ")"

instance Eq Dice where
  d1 == d2 = d1 `compare` d2 == EQ

instance Ord Dice where
  Dice d1 `compare` Dice d2 = (add $ compare <$> d1 <*> d2) `compare` 0
    where
      add = sum . map (\case {LT -> -1; EQ -> 0; GT -> 1})

dices n = Dice <$> (nub $ sort <$> replicateM n [1..n])

nonTrans dice = filter (\x -> last x < head x) . go
  where
    go 0 = []
    go 1 = sequence [dice]
    go n = do
      (a:as) <- go (n-1)
      b <- filter (< a) dice
      return (b:a:as)


NB. unique list of all y faced dice
udice=: {{ 1+~./:~"1 (#: ,@i.)y#y }}

NB. which dice are less than which other dice?
NB. y here is a result of udice
lthan=: {{ 0>*@(+/)@,@:*@(-/)"1/~ y}}

NB. "less than loops" length x, for y sided non-transitive dice
cycles=: {{
  ud=. udice y
  lt=. lthan ud
  extend=. [:; lt{{< y,"1 0 y-.~I.m{~{:y }}"1
  r=. ; extend^:(x-1)&.> i.#ud
  ud{~ ~.((i.<./)|.])"1 r #~ lt{~({:,&.>{.)|:r
}}


#lang racket

(struct ± (x dx) #:transparent
  #:methods gen:custom-write
  [(define (write-proc a port mode) (display (±->string a) port))])

(define/match (±+ a [b 0])
  [((± x dx) (± y dy)) (± (+ x y) (norm dx dy))]
  [((± x dx) c) (± (+ x c) dx)]
  [(_ (± y dy)) (±+ b a)])

(define/match (±* a b)
  [((± x dx) (± y dy)) (± (* x y) (* x y (norm (/ dx x) (/ dy y))))]
  [((± x dx) c) (± (* x c) (abs (* c dx)))]
  [(_ (± y dy)) (±* b a)])

(define/match (±- a [b #f])
  [(a #f) (±* -1 a)]
  [(a b) (±+ a (±* -1 b))])

(define/match (±/ a b)
  [((± x dx) (± y dy)) (± (/ x y) (/ x y (norm (/ dx x) (/ dy y))))]
  [((± _ _) c) (±* a (/ 1 c))])

(define/match (±expt a c)
  [((± x dx) c) (± (expt x c) (abs (* (expt x c) (/ dx x))))])

(define/match (norm a b)
  [((± x dx) (± y dy)) (±expt (±+ (±expt a 2) (±expt b 2)) 0.5)]
  [(x y) (sqrt (+ (sqr x) (sqr y)))])

(define/match (±->string x [places 3])
  [((± x dx) p) (string-join (map (λ (s) (real->decimal-string s p))
                                  (list x dx))" ± ")])

;; Test
;;
(define x1 (± 100 1.1))
(define y1 (± 50 1.2))
(define x2 (± 200 2.2))
(define y2 (± 100 2.3))
(norm (±- x1 x2) (±- y1 y2))


# cache of independent sources so we can make them all the same length.
# (Because Raku does not yet have a longest-zip metaoperator.)
my @INDEP;

class Approx does Numeric {
    has Real $.x;	# The mean.
    has $.c;		# The components of error.

    multi method Str  { sprintf "%g±%.3g", $!x, $.σ }
    multi method Bool { abs($!x) > $.σ }

    method variance { [+] @.c X** 2 }
    method σ { sqrt self.variance }
}

multi approx($x,$c) { Approx.new: :$x, :$c }
multi approx($x) { Approx.new: :$x, :c[0 xx +@INDEP] }

# Each ± gets its own source slot.
multi infix:<±>($a, $b) {
    .push: 0 for @INDEP; # lengthen older component lists
    my $c = [ flat 0 xx @INDEP, $b ];
    @INDEP.push: $c;	 # add new component list

    approx $a, $c;
}

multi prefix:<->(Approx $a) { approx -$a.x, [$a.c.map: -*] }

multi infix:<+>($a, Approx $b) { approx($a) + $b }
multi infix:<+>(Approx $a, $b) { $a + approx($b) }
multi infix:<+>(Approx $a, Approx $b) { approx $a.x + $b.x, [$a.c Z+ $b.c] }

multi infix:<->($a, Approx $b) { approx($a) - $b }
multi infix:<->(Approx $a, $b) { $a - approx($b) }
multi infix:<->(Approx $a, Approx $b) { approx $a.x - $b.x, [$a.c Z- $b.c] }

multi covariance(Real   $a, Real   $b) { 0 }
multi covariance(Approx $a, Approx $b) { [+] $a.c Z* $b.c }

multi infix:«<=>»(Approx $a, Approx $b) { $a.x <=> $b.x }
multi infix:<cmp>(Approx $a, Approx $b) { $a.x <=> $b.x }

multi infix:<*>($a, Approx $b) { approx($a) * $b }
multi infix:<*>(Approx $a, $b) { $a * approx($b) }
multi infix:<*>(Approx $a, Approx $b) {
    approx $a.x * $b.x,
           [$a.c.map({$b.x * $_}) Z+ $b.c.map({$a.x * $_})];
}

multi infix:</>($a, Approx $b) { approx($a) / $b }
multi infix:</>(Approx $a, $b) { $a / approx($b) }
multi infix:</>(Approx $a, Approx $b) {
    approx $a.x / $b.x,
           [ $a.c.map({ $_ / $b.x }) Z+ $b.c.map({ $a.x * $_ / $b.x / $b.x }) ];
}

multi sqrt(Approx $a) {
    my $x = sqrt($a.x);
    approx $x, [ $a.c.map: { $_ / 2 / $x } ];
}

multi infix:<**>(Approx $a, Real $b) { $a ** approx($b) }
multi infix:<**>(Approx $a is copy, Approx $b) {
	my $ax = $a.x;
	my $bx = $b.x;
	my $fbx = floor $b.x;
	if $ax < 0 {
	    if $fbx != $bx or $fbx +& 1 {
		die "Can't take power of negative number $ax";
	    }
	    $a = -$a;
	}
	exp($b * log $a);
}

multi exp(Approx $a) {
	my $x = exp($a.x);
	approx $x, [ $a.c.map: { $x * $_ } ];
}

multi log(Approx $a) {
	my $x0 = $a.x;
	approx log($x0), [ $a.c.map: { $_ / $x0 }];
}

# Each ± sets up an independent source component.
my $x1 = 100 ± 1.1;
my $x2 = 200 ± 2.2;
my $y1 = 50  ± 1.2;
my $y2 = 100 ± 2.3;

# The standard task.
my $z1 = sqrt(($x1 - $x2) ** 2 + ($y1 - $y2) ** 2);
say "distance: $z1\n";

# Just showing off.
my $a = $x1 + $x2;
my $b = $y1 - 2 * $x2;
say "covariance between $a and $b: ", covariance($a,$b);


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
    private static List<List<Integer>> fourFaceCombos() {
        List<List<Integer>> res = new ArrayList<>();
        Set<Integer> found = new HashSet<>();

        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= 4; j++) {
                for (int k = 1; k <= 4; k++) {
                    for (int l = 1; l <= 4; l++) {
                        List<Integer> c = IntStream.of(i, j, k, l).sorted().boxed().collect(Collectors.toList());

                        int key = 64 * (c.get(0) - 1) + 16 * (c.get(1) - 1) + 4 * (c.get(2) - 1) + (c.get(3) - 1);
                        if (found.add(key)) {
                            res.add(c);
                        }
                    }
                }
            }
        }

        return res;
    }

    private static int cmp(List<Integer> x, List<Integer> y) {
        int xw = 0;
        int yw = 0;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (x.get(i) > y.get(j)) {
                    xw++;
                } else if (x.get(i) < y.get(j)) {
                    yw++;
                }
            }
        }
        return Integer.compare(xw, yw);
    }

    private static List<List<List<Integer>>> findIntransitive3(List<List<Integer>> cs) {
        int c = cs.size();
        List<List<List<Integer>>> res = new ArrayList<>();

        for (int i = 0; i < c; i++) {
            for (int j = 0; j < c; j++) {
                if (cmp(cs.get(i), cs.get(j)) == -1) {
                    for (List<Integer> kl : cs) {
                        if (cmp(cs.get(j), kl) == -1 && cmp(kl, cs.get(i)) == -1) {
                            res.add(List.of(cs.get(i), cs.get(j), kl));
                        }
                    }
                }
            }
        }

        return res;
    }

    private static List<List<List<Integer>>> findIntransitive4(List<List<Integer>> cs) {
        int c = cs.size();
        List<List<List<Integer>>> res = new ArrayList<>();

        for (int i = 0; i < c; i++) {
            for (int j = 0; j < c; j++) {
                if (cmp(cs.get(i), cs.get(j)) == -1) {
                    for (int k = 0; k < cs.size(); k++) {
                        if (cmp(cs.get(j), cs.get(k)) == -1) {
                            for (List<Integer> ll : cs) {
                                if (cmp(cs.get(k), ll) == -1 && cmp(ll, cs.get(i)) == -1) {
                                    res.add(List.of(cs.get(i), cs.get(j), cs.get(k), ll));
                                }
                            }
                        }
                    }
                }
            }
        }

        return res;
    }

    public static void main(String[] args) {
        List<List<Integer>> combos = fourFaceCombos();
        System.out.printf("Number of eligible 4-faced dice: %d%n", combos.size());
        System.out.println();

        List<List<List<Integer>>> it3 = findIntransitive3(combos);
        System.out.printf("%d ordered lists of 3 non-transitive dice found, namely:%n", it3.size());
        for (List<List<Integer>> a : it3) {
            System.out.println(a);
        }
        System.out.println();

        List<List<List<Integer>>> it4 = findIntransitive4(combos);
        System.out.printf("%d ordered lists of 4 non-transitive dice found, namely:%n", it4.size());
        for (List<List<Integer>> a : it4) {
            System.out.println(a);
        }
    }
}


/*REXX program calculates the distance between two points (2D)  with error propagation. */
parse arg a b .                                           /*obtain arguments from the CL*/
if a=='' | a==","  then a= '100±1.1,  50±1.2'             /*Not given? Then use default.*/
if b=='' | b==","  then b= '200±2.2, 100±2.3'             /* "    "      "   "     "    */
parse var a  ax ',' ay;     parse var b  bx ',' by        /*obtain X,Y from A & B point.*/
parse var ax ax '±' axe;    parse var bx bx '±' bxE       /*   "   err   "  Ax  and  Bx.*/
parse var ay ay '±' aye;    parse var by by '±' byE       /*   "    "    "  Ay   "   By.*/
if axE==''  then axE= 0;    if bxE==""  then bxE= 0       /*No error?  Then use default.*/
if ayE==''  then ayE= 0;    if byE==""  then byE= 0       /* "   "       "   "     "    */
   say ' A point (x,y)=   ' ax "±"   axE',   ' ay "±" ayE /*display  A  point (with err)*/
   say ' B point (x.y)=   ' bx "±"   bxE',   ' by "±" byE /*   "     B    "      "   "  */
   say                                                    /*blank line for the eyeballs.*/
dx= ax-bx;  dxE= sqrt(axE**2 + bxE**2); xe= #(dx, 2, dxE) /*compute  X distances (& err)*/
dy= ay-by;  dyE= sqrt(ayE**2 + byE**2); ye= #(dy, 2, dyE) /*   "     Y     "      "  "  */
D= sqrt(dx**2 + dy**2)                                    /*compute the   2D  distance. */
   say 'distance=' D "±" #(D**2, .5, sqrt(xE**2 + yE**2)) /*display  "     "      "     */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
#: procedure; arg x,p,e; if p=.5 then z=1/sqrt(abs(x)); else z=abs(x)**(p-1); return p*e*z
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x;  if x=0  then return 0;  d=digits();  numeric digits;  h=d+6
      numeric form;  parse value format(x,2,1,,0) 'E0' with g "E" _ .;    g=g * .5'e'_ % 2
      m.=9;       do j=0  while h>9;       m.j=h;               h=h%2+1;        end  /*j*/
                  do k=j+5  to 0  by -1;   numeric digits m.k;  g=(g+x/g)*.5;   end  /*k*/
      numeric digits d;                    return g/1
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x;  if x=0  then return 0;  d=digits();  numeric digits;  h=d+6
      numeric form;  parse value format(x,2,1,,0) 'E0' with g "E" _ .;   g= g * .5'e'_ % 2
      m.= 9;   do j=0  while h>9;       m.j= h;               h= h%2+1;        end  /*j*/
               do k=j+5  to 0  by -1;   numeric digits m.k;   g= (g+x/g)*.5;   end  /*k*/
      numeric digits d;                 return g/1


import Base.>, Base.<
using Memoize, Combinatorics

struct Die
    name::String
    faces::Vector{Int}
end

""" Compares two die returning 1, -1 or 0 for operators >, < == """
function cmpd(die1, die2)
    # Numbers of times one die wins against the other for all combinations
    # cmp(x, y) is `(x > y) - (y > x)` to return 1, 0, or -1 for numbers
    tot = [0, 0, 0]
    for d in Iterators.product(die1.faces, die2.faces)
        tot[2 + (d[1] > d[2]) - (d[2] > d[1])] += 1
    end
    return (tot[3] > tot[1]) - (tot[1] > tot[3])
end

Base.:>(d1::Die, d2::Die) = cmpd(d1, d2) == 1
Base.:<(d1::Die, d2::Die) = cmpd(d1, d2) == -1

""" True iff ordering of die in dice is non-transitive """
isnontrans(dice) = all(x -> x[1] < x[2], zip(dice[1:end-1], dice[2:end])) && dice[1] > dice[end]

findnontrans(alldice, n=3) = [perm for perm in permutations(alldice, n) if isnontrans(perm)]

function possible_dice(sides, mx)
    println("\nAll possible 1..$mx $sides-sided dice")
    dice = [Die("D $(n+1)", [i for i in f]) for (n, f) in
        enumerate(Iterators.product(fill(1:mx, sides)...))]
    println("  Created $(length(dice)) dice")
    println("  Remove duplicate with same bag of numbers on different faces")
    uniquedice = collect(values(Dict(sort(d.faces) => d for d in dice)))
    println("   Return $(length(uniquedice)) filtered dice")
    return uniquedice
end

""" Compares two die returning their relationship of their names as a string """
function verbosecmp(die1, die2)
    # Numbers of times one die wins against the other for all combinations
    win1 = sum(p[1] > p[2] for p in Iterators.product(die1.faces, die2.faces))
    win2 = sum(p[2] > p[1] for p in Iterators.product(die1.faces, die2.faces))
    n1, n2 = die1.name, die2.name
    return win1 > win2 ? "$n1 > $n2" : win1 < win2 ? "$n1 < $n2" : "$n1 = $n2"
end

""" Dice cmp function with verbose extra checks """
function verbosedicecmp(dice)
    return join([[verbosecmp(x, y) for (x, y) in zip(dice[1:end-1], dice[2:end])];
                 [verbosecmp(dice[1], dice[end])]], ", ")
end

function testnontransitivedice(faces)
    dice = possible_dice(faces, faces)
    for N in (faces < 5 ? [3, 4] : [3])  # length of non-transitive group of dice searched for
        nontrans = unique(map(x -> sort!(x, lt=(x, y)->x.name<y.name), findnontrans(dice, N)))
        println("\n  Unique sorted non_transitive length-$N combinations found: $(length(nontrans))")
        for list in (faces < 5 ? nontrans : [nontrans[end]])
            println(faces < 5 ? "" : "  Only printing last example for brevity")
            for (i, die) in enumerate(list)
                println("     $die$(i < N - 1 ? "," : "]")")
            end
        end
        if !isempty(nontrans)
            println("\n  More verbose comparison of last non_transitive result:")
            println(" ", verbosedicecmp(nontrans[end]))
        end
        println("\n  ====")
    end
end

@time testnontransitivedice(3)
@time testnontransitivedice(4)
@time testnontransitivedice(5)
@time testnontransitivedice(6)


fun fourFaceCombos(): List<Array<Int>> {
    val res = mutableListOf<Array<Int>>()
    val found = mutableSetOf<Int>()
    for (i in 1..4) {
        for (j in 1..4) {
            for (k in 1..4) {
                for (l in 1..4) {
                    val c = arrayOf(i, j, k, l)
                    c.sort()
                    val key = 64 * (c[0] - 1) + 16 * (c[1] - 1) + 4 * (c[2] - 1) + (c[3] - 1)
                    if (!found.contains(key)) {
                        found.add(key)
                        res.add(c)
                    }
                }
            }
        }
    }
    return res
}

fun cmp(x: Array<Int>, y: Array<Int>): Int {
    var xw = 0
    var yw = 0
    for (i in 0 until 4) {
        for (j in 0 until 4) {
            if (x[i] > y[j]) {
                xw++
            } else if (y[j] > x[i]) {
                yw++
            }
        }
    }
    if (xw < yw) {
        return -1
    }
    if (xw > yw) {
        return 1
    }
    return 0
}

fun findIntransitive3(cs: List<Array<Int>>): List<Array<Array<Int>>> {
    val c = cs.size
    val res = mutableListOf<Array<Array<Int>>>()

    for (i in 0 until c) {
        for (j in 0 until c) {
            if (cmp(cs[i], cs[j]) == -1) {
                for (k in 0 until c) {
                    if (cmp(cs[j], cs[k]) == -1 && cmp(cs[k], cs[i]) == -1) {
                        res.add(arrayOf(cs[i], cs[j], cs[k]))
                    }
                }
            }
        }
    }

    return res
}

fun findIntransitive4(cs: List<Array<Int>>): List<Array<Array<Int>>> {
    val c = cs.size
    val res = mutableListOf<Array<Array<Int>>>()

    for (i in 0 until c) {
        for (j in 0 until c) {
            if (cmp(cs[i], cs[j]) == -1) {
                for (k in 0 until c) {
                    if (cmp(cs[j], cs[k]) == -1) {
                        for (l in 0 until c) {
                            if (cmp(cs[k], cs[l]) == -1 && cmp(cs[l], cs[i]) == -1) {
                                res.add(arrayOf(cs[i], cs[j], cs[k], cs[l]))
                            }
                        }
                    }
                }
            }
        }
    }

    return res
}

fun main() {
    val combos = fourFaceCombos()
    println("Number of eligible 4-faced dice: ${combos.size}")
    println()

    val it3 = findIntransitive3(combos)
    println("${it3.size} ordered lists of 3 non-transitive dice found, namely:")
    for (a in it3) {
        println(a.joinToString(", ", "[", "]") { it.joinToString(", ", "[", "]") })
    }
    println()

    val it4 = findIntransitive4(combos)
    println("${it4.size} ordered lists of 4 non-transitive dice found, namely:")
    for (a in it4) {
        println(a.joinToString(", ", "[", "]") { it.joinToString(", ", "[", "]") })
    }
}


class NumberWithUncertainty
  def initialize(number, error)
    @num = number
    @err = error.abs
  end
  attr_reader :num, :err

  def +(other)
    if other.kind_of?(self.class)
      self.class.new(num + other.num, Math::hypot(err, other.err))
    else
      self.class.new(num + other, err)
    end
  end

  def -(other)
    if other.kind_of?(self.class)
      self.class.new(num - other.num, Math::hypot(err, other.err))
    else
      self.class.new(num - other, err)
    end
  end

  def *(other)
    if other.kind_of?(self.class)
      prod = num * other.num
      e = Math::hypot((prod * err / num), (prod * other.err / other.num))
      self.class.new(prod, e)
    else
      self.class.new(num * other, (err * other).abs)
    end
  end

  def /(other)
    if other.kind_of?(self.class)
      quo = num / other.num
      e = Math::hypot((quo * err / num), (quo * other.err / other.num))
      self.class.new(quo, e)
    else
      self.class.new(num / other, (err * other).abs)
    end
  end

  def **(exponent)
    Float(exponent) rescue raise ArgumentError, "not an number: #{exponent}"
    prod = num ** exponent
    self.class.new(prod, (prod * exponent * err / num).abs)
  end

  def sqrt
    self ** 0.5
  end

  def to_s
    "#{num} \u00b1 #{err}"
  end
end

x1 = NumberWithUncertainty.new(100, 1.1)
y1 = NumberWithUncertainty.new( 50, 1.2)
x2 = NumberWithUncertainty.new(200, 2.2)
y2 = NumberWithUncertainty.new(100, 2.3)

puts ((x1 - x2) ** 2 + (y1 - y2) ** 2).sqrt


%Non transitive dice. Nigel Galloway, September 14th., 2020
int: die; int: faces; set of int: values;
predicate pN(array[1..faces] of var values: n, array[1..faces] of var values: g) = sum(i in 1..faces,j in 1..faces)(if n[i]<g[j] then 1 elseif n[i]>g[j] then -1 else 0 endif)>0;
predicate pG(array[1..faces] of var values: n) = forall(g in 1..faces-1)(n[g]<=n[g+1]);
array[1..die,1..faces] of var values: g;
constraint forall(n in 1..die)(pG(g[n,1..faces]));
constraint forall(n in 1..die-1)(pN(g[n,1..faces],g[n+1,1..faces]));
constraint pN(g[die,1..faces],g[1,1..faces]);
output[join(" ",[show(g[n,1..faces])++"<"++show(g[n+1,1..faces]) | n in 1..die-1])," "++show(g[die,1..faces])++">"++show(g[1,1..faces])];


import algorithm, sequtils, sets, strformat
import itertools

type Die = object
  name: string
  faces: seq[int]

####################################################################################################
# Die functions.

func `$`(die: Die): string =
  ## Return the string representation of a Die.
  &"({die.name}: {($die.faces)[1..^1]})"

func cmp(die1, die2: Die): int =
  ## Compare two die returning 1, -1 or 0 for operators >, < ==.
  var tot: array[3, int]
  for d in product(die1.faces, die2.faces):
    inc tot[1 + ord(d[1] < d[0]) - ord(d[0] < d[1])]
  result = ord(tot[0] < tot[2]) - ord(tot[2] < tot[0])

func verboseCmp(die1, die2: Die): string =
  ## Compare tow die returning a string.
  var win1, win2 = 0
  for (d1, d2) in product(die1.faces, die2.faces):
    inc win1, ord(d1 > d2)
    inc win2, ord(d2 > d1)
  result = if win1 > win2: &"{die1.name} > {die2.name}"
           elif win1 < win2: &"{die1.name} < {die2.name}"
           else: &"{die1.name} = {die2.name}"

func `>`(die1, die2: Die): bool = cmp(die1, die2) > 0
func `<=`(die1, die2: Die): bool = cmp(die1, die2) <= 0

####################################################################################################
# Added a permutation iterator as that of "itertools" doesn't allow to specify the length.

iterator permutations[T](values: openArray[T]; r: int): seq[T] {.closure} =
  ## Yield permutations of length "r" with elements taken from "values".
  let n = values.len
  if r > n: return
  var indices = toSeq(0..<n)
  var cycles = toSeq(countdown(n, n - r + 1))
  var perm = values[0..<r]
  yield perm
  if n == 0: return
  while true:
    var exit = true
    for i in countdown(r - 1, 0):
      dec cycles[i]
      if cycles[i] == 0:
        discard indices.rotateLeft(i..indices.high, 1)
        cycles[i] = n - i
      else:
        let j = cycles[i]
        swap indices[i], indices[^j]
        for iperm, ivalues in indices[0..<r]:
          perm[iperm] = values[ivalues]
        yield perm
        exit = false
        break
    if exit: return

####################################################################################################
# Dice functions.

func isNonTrans(dice: openArray[Die]): bool =
  ## Return true if ordering of die in dice is non-transitive.
  for i in 1..dice.high:
    if dice[i] <= dice[i-1]: return false
  result = dice[0] > dice[^1]

func findNonTrans(allDice: openArray[Die]; n = 3): seq[seq[Die]] =
  ## Return the list of non-transitive dice.
  for perm in permutations(allDice, n):
    if perm.isNontrans:
      result.add perm

proc possibleDice(sides, maxval: Positive): seq[Die] =
  ## Return the list of possible dice with given number of sides and maximum value.

  echo &"All possible 1..{maxval} {sides}-sided dice."
  var dice: seq[Die]
  var n = 1
  for faces in product(toSeq(1..maxval), repeat = sides):
    dice.add Die(name: &"D{n}", faces: faces)
    inc n
  echo &"  Created {dice.len} dice."
  echo "  Remove duplicate with same bag of numbers on different faces."
  var found: HashSet[seq[int]]
  for d in dice:
    let count = sorted(d.faces)
    if count notin found:
      found.incl count
      result.add d
  echo &"   Return {result.len} filtered dice."

func verboseDiceCmp(dice: openArray[Die]): string =
  ## Return the verbose comparison of dice.
  for i in 1..dice.high:
    result.add verboseCmp(dice[i-1], dice[i]) & ", "
  result.add verboseCmp(dice[0], dice[^1])

#———————————————————————————————————————————————————————————————————————————————————————————————————

when isMainModule:

  let dice = possibleDice(sides = 4, maxval = 4)
  for n in [3, 4]:
    let nonTrans = dice.findNonTrans(n)
    echo &"\n  Non-transitive length-{n} combinations found: {nonTrans.len}."
    for list in nonTrans:
      echo ""
      for i, die in list:
        echo "    ", if i == 0: '[' else: ' ', die, if i == list.high: "]" else: ","
    if nonTrans.len != 0:
      echo &"\n  More verbose comparison of last non-transitive result:"
      echo "  ", verboseDiceCmp(nonTrans[^1])
    echo "\n  ===="


use strict;
use warnings;

sub fourFaceCombs {
    my %found = ();
    my @res = ();
    for (my $i = 1; $i <= 4; $i++) {
        for (my $j = 1; $j <= 4; $j++) {
            for (my $k = 1; $k <= 4; $k++) {
                for (my $l = 1; $l <= 4; $l++) {
                    my @c = sort ($i, $j, $k, $l);
                    my $key = 0;
                    for my $p (@c) {
                        $key = 10 * $key + $p;
                    }
                    if (not exists $found{$key}) {
                        $found{$key} = 1;
                        push @res, \@c;
                    }
                }
            }
        }
    }
    return @res;
}

sub compare {
    my $xref = shift;
    my $yref = shift;

    my @x = @$xref;
    my $xw = 0;

    my @y = @$yref;
    my $yw = 0;

    for my $i (@x) {
        for my $j (@y) {
            if ($i < $j) {
                $yw++;
            }
            if ($j < $i) {
                $xw++;
            }
        }
    }

    if ($xw < $yw) {
        return -1;
    }
    if ($yw < $xw) {
        return 1;
    }
    return 0;
}

sub findIntransitive3 {
    my $dice_ref = shift;
    my @dice = @$dice_ref;
    my $len = scalar @dice;

    my @res = ();
    for (my $i = 0; $i < $len; $i++) {
        for (my $j = 0; $j < $len; $j++) {
            my $first = compare($dice[$i], $dice[$j]);
            if ($first == 1) {
                for (my $k = 0; $k < $len; $k++) {
                    my $second = compare($dice[$j], $dice[$k]);
                    if ($second == 1) {
                        my $third = compare($dice[$k], $dice[$i]);
                        if ($third == 1) {
                            my $d1r = $dice[$i];
                            my $d2r = $dice[$j];
                            my $d3r = $dice[$k];
                            my @itd = ($d1r, $d2r, $d3r);
                            push @res, \@itd;
                        }
                    }
                }
            }
        }
    }
    return @res;
}

sub findIntransitive4 {
    my $dice_ref = shift;
    my @dice = @$dice_ref;
    my $len = scalar @dice;

    my @res = ();
    for (my $i = 0; $i < $len; $i++) {
        for (my $j = 0; $j < $len; $j++) {
            for (my $k = 0; $k < $len; $k++) {
                for (my $l = 0; $l < $len; $l++) {
                    my $first = compare($dice[$i], $dice[$j]);
                    if ($first == 1) {
                        my $second = compare($dice[$j], $dice[$k]);
                        if ($second == 1) {
                            my $third = compare($dice[$k], $dice[$l]);
                            if ($third == 1) {
                                my $fourth = compare($dice[$l], $dice[$i]);
                                if ($fourth == 1) {
                                    my $d1r = $dice[$i];
                                    my $d2r = $dice[$j];
                                    my $d3r = $dice[$k];
                                    my $d4r = $dice[$l];
                                    my @itd = ($d1r, $d2r, $d3r, $d4r);
                                    push @res, \@itd;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return @res;
}

sub main {
    my @dice = fourFaceCombs();
    my $len = scalar @dice;
    print "Number of eligible 4-faced dice: $len\n\n";

    my @it3 = findIntransitive3(\@dice);
    my $count3 = scalar @it3;
    print "$count3 ordered lists of 3 non-transitive dice found, namely:\n";
    for my $itref (@it3) {
        print "[ ";
        for my $r (@$itref) {
            print "[@$r] ";
        }
        print "]\n";
    }
    print "\n";

    my @it4 = findIntransitive4(\@dice);
    my $count = scalar @it4;
    print "$count ordered lists of 4 non-transitive dice found, namely:\n";
    for my $itref (@it4) {
        print "[ ";
        for my $r (@$itref) {
            print "[@$r] ";
        }
        print "]\n";
    }
}

main();


import java.lang.Math._

class Approx(val ν: Double, val σ: Double = 0.0) {
    def this(a: Approx) = this(a.ν, a.σ)
    def this(n: Number) = this(n.doubleValue(), 0.0)

    override def toString = s"$ν ±$σ"

    def +(a: Approx) = Approx(ν + a.ν, sqrt(σ * σ + a.σ * a.σ))
    def +(d: Double) = Approx(ν + d, σ)
    def -(a: Approx) = Approx(ν - a.ν, sqrt(σ * σ + a.σ * a.σ))
    def -(d: Double) = Approx(ν - d, σ)

    def *(a: Approx) = {
        val v = ν * a.ν
        Approx(v, sqrt(v * v * σ * σ / (ν * ν) + a.σ * a.σ / (a.ν * a.ν)))
    }

    def *(d: Double) = Approx(ν * d, abs(d * σ))

    def /(a: Approx) = {
        val t = ν / a.ν
        Approx(t, sqrt(t * t * σ * σ / (ν * ν) + a.σ * a.σ / (a.ν * a.ν)))
    }

    def /(d: Double) = Approx(ν / d, abs(d * σ))

    def ^(d: Double) = {
        val t = pow(ν, d)
        Approx(t, abs(t * d * σ / ν))
    }
}

object Approx { def apply(ν: Double, σ: Double = 0.0) = new Approx(ν, σ) }

object NumericError extends App {
    def √(a: Approx) = a^0.5
    val x1 = Approx(100.0, 1.1)
    val x2 = Approx(50.0, 1.2)
    val y1 = Approx(200.0, 2.2)
    val y2 = Approx(100.0, 2.3)
    println(√(((x1 - x2)^2.0) + ((y1 - y2)^2.0)))  // => 111.80339887498948 ±2.938366893361004
}