title: Simplification of validators.

-- in.cue --
package main

import (
	"strings"
	"time"
)

t1: {
	#Test: {
		#HTTP:  =~"^http://"
		#SSH:   !~"^ssh://"
		#USER:  strings.MinRunes(3)
		source: #HTTP | #SSH | #USER | #Test
	}

	foo: #Test & {
		source: "http://blablabla"
	}

	bar: #Test & {
		source: foo
	}
}

t2: {
	str: "foo"
	a:   =~str
	b:   =~"foo"
	c:   a & b & a & b

	d: time.Time
	e: time.Time()
	f: d & e & d & e
}
-- out/evalalpha/stats --
Leaks:  69
Freed:  0
Reused: 0
Allocs: 69
Retain: 0

Unifications: 29
Conjuncts:    79
Disjuncts:    16

CloseIDElems: 35
NumCloseIDs: 22
-- diff/-out/evalalpha/stats<==>+out/eval/stats --
diff old new
--- old
+++ new
@@ -1,9 +1,12 @@
-Leaks:  0
-Freed:  121
-Reused: 107
-Allocs: 14
+Leaks:  69
+Freed:  0
+Reused: 0
+Allocs: 69
 Retain: 0
 
-Unifications: 65
-Conjuncts:    205
-Disjuncts:    121
+Unifications: 29
+Conjuncts:    79
+Disjuncts:    16
+
+CloseIDElems: 35
+NumCloseIDs: 22
-- out/eval/stats --
Leaks:  0
Freed:  121
Reused: 107
Allocs: 14
Retain: 0

Unifications: 65
Conjuncts:    205
Disjuncts:    121
-- out/evalalpha --
(struct){
  t1: (struct){
    #Test: (#struct){
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
      source: (string){ |((string){ =~"^http://" }, (string){ !~"^ssh://" }, (string){ strings.MinRunes(3) }) }
    }
    foo: (#struct){
      source: (string){ "http://blablabla" }
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
    }
    bar: (#struct){
      source: (#struct){
        source: (string){ "http://blablabla" }
        #HTTP: (string){ =~"^http://" }
        #SSH: (string){ !~"^ssh://" }
        #USER: (string){ strings.MinRunes(3) }
      }
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
    }
  }
  t2: (struct){
    str: (string){ "foo" }
    a: (string){ =~"foo" }
    b: (string){ =~"foo" }
    c: (string){ =~"foo" }
    d: (string){ time.Time() }
    e: (string){ time.Time() }
    f: (string){ time.Time() }
  }
}
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -7,21 +7,21 @@
       source: (string){ |((string){ =~"^http://" }, (string){ !~"^ssh://" }, (string){ strings.MinRunes(3) }) }
     }
     foo: (#struct){
-      #HTTP: (string){ =~"^http://" }
-      #SSH: (string){ !~"^ssh://" }
-      #USER: (string){ strings.MinRunes(3) }
       source: (string){ "http://blablabla" }
+      #HTTP: (string){ =~"^http://" }
+      #SSH: (string){ !~"^ssh://" }
+      #USER: (string){ strings.MinRunes(3) }
     }
     bar: (#struct){
-      #HTTP: (string){ =~"^http://" }
-      #SSH: (string){ !~"^ssh://" }
-      #USER: (string){ strings.MinRunes(3) }
       source: (#struct){
+        source: (string){ "http://blablabla" }
         #HTTP: (string){ =~"^http://" }
         #SSH: (string){ !~"^ssh://" }
         #USER: (string){ strings.MinRunes(3) }
-        source: (string){ "http://blablabla" }
       }
+      #HTTP: (string){ =~"^http://" }
+      #SSH: (string){ !~"^ssh://" }
+      #USER: (string){ strings.MinRunes(3) }
     }
   }
   t2: (struct){
-- diff/todo/p3 --
Reordering.
-- out/eval --
(struct){
  t1: (struct){
    #Test: (#struct){
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
      source: (string){ |((string){ =~"^http://" }, (string){ !~"^ssh://" }, (string){ strings.MinRunes(3) }) }
    }
    foo: (#struct){
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
      source: (string){ "http://blablabla" }
    }
    bar: (#struct){
      #HTTP: (string){ =~"^http://" }
      #SSH: (string){ !~"^ssh://" }
      #USER: (string){ strings.MinRunes(3) }
      source: (#struct){
        #HTTP: (string){ =~"^http://" }
        #SSH: (string){ !~"^ssh://" }
        #USER: (string){ strings.MinRunes(3) }
        source: (string){ "http://blablabla" }
      }
    }
  }
  t2: (struct){
    str: (string){ "foo" }
    a: (string){ =~"foo" }
    b: (string){ =~"foo" }
    c: (string){ =~"foo" }
    d: (string){ time.Time() }
    e: (string){ time.Time() }
    f: (string){ time.Time() }
  }
}
-- out/compile --
--- in.cue
{
  t1: {
    #Test: {
      #HTTP: =~"^http://"
      #SSH: !~"^ssh://"
      #USER: 〈import;strings〉.MinRunes(3)
      source: (〈0;#HTTP〉|〈0;#SSH〉|〈0;#USER〉|〈1;#Test〉)
    }
    foo: (〈0;#Test〉 & {
      source: "http://blablabla"
    })
    bar: (〈0;#Test〉 & {
      source: 〈1;foo〉
    })
  }
  t2: {
    str: "foo"
    a: =~〈0;str〉
    b: =~"foo"
    c: (((〈0;a〉 & 〈0;b〉) & 〈0;a〉) & 〈0;b〉)
    d: 〈import;time〉.Time
    e: 〈import;time〉.Time()
    f: (((〈0;d〉 & 〈0;e〉) & 〈0;d〉) & 〈0;e〉)
  }
}
