Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
stage-L3-2016
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Aliaume Lopez
stage-L3-2016
Commits
278f3697
Commit
278f3697
authored
Jul 18, 2016
by
Aliaume Lopez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewriting huge progress
parent
7e2f733a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1683 additions
and
160 deletions
+1683
-160
circuits.ml
circuits.ml
+575
-153
ptg.ml
ptg.ml
+624
-0
rewriting.ml
rewriting.ml
+475
-0
utils.ml
utils.ml
+9
-7
No files found.
circuits.ml
View file @
278f3697
...
...
@@ -2,24 +2,40 @@
*
* circuits.ml
*
*
Dan Ghica
*
Aliaume Lopez
*
* Entry point of the program
* generates dot output,
* handles graph reduction,
* embedded DSL, and all.
* TODO
*
* « aliaume hook » is the
* hook from all the rest of
* the librairies into this
* file to interface the new
* language and definition to
* the new model
* 1) rules
* a) Dangle : propagating disconnect nodes
* b) Garbage collect nodes
* c) fork constant
* d) gate reduce (end the work)
*
* 3) compiling from dags
*
* 4) waveforms ?
*
*)
open
Dot
;;
let
rec
zip_with_3
f
a
b
c
=
match
(
a
,
b
,
c
)
with
|
[]
,
[]
,
[]
->
[]
|
a1
::
a2
,
b1
::
b2
,
c1
::
c2
->
(
f
a1
b1
c1
)
::
zip_with_3
f
a2
b2
c2
;;
let
rec
zip_with_4
f
a
b
c
d
=
match
(
a
,
b
,
c
,
d
)
with
|
[]
,
[]
,
[]
,
[]
->
[]
|
a1
::
a2
,
b1
::
b2
,
c1
::
c2
,
d1
::
d2
->
(
f
a1
b1
c1
d1
)
::
zip_with_4
f
a2
b2
c2
d2
;;
let
rec
zip_with
f
a
b
=
match
(
a
,
b
)
with
|
[]
,
[]
->
[]
|
a1
::
a2
,
b1
::
b2
->
(
f
a1
b1
)
::
zip_with
f
a2
b2
;;
module
ComparableInts
=
struct
type
t
=
int
...
...
@@ -104,8 +120,6 @@ type label =
*
*)
type
ptg
=
{
maxid
:
int
;
(* the maximum id inside the graph *)
(* naturally have a notion of order *)
iports
:
nid
list
;
oports
:
nid
list
;
...
...
@@ -134,26 +148,6 @@ type ptg = {
}
(*** PRETTY PRINTING ***)
let
string_of_gate
=
function
|
Fork
->
"F"
|
Join
->
"J"
|
Nmos
->
"N"
|
Pmos
->
"P"
|
Box
s
->
"B "
^
s
|
Wait
->
"W"
|
Mux
->
"M"
|
Disconnect
->
"D"
;;
let
string_of_value
=
function
|
High
->
"H"
|
Low
->
"L"
|
Top
->
"T"
|
Bottom
->
"Z"
;;
let
string_of_label
=
function
|
Value
v
->
string_of_value
v
|
Gate
g
->
string_of_gate
g
;;
(**
...
...
@@ -195,31 +189,6 @@ let pp_ptg ptg = ptg |> string_of_ptg |> print_string;;
(**** DOT CONVERSION ****)
let
example_ptg
=
{
maxid
=
6
;
iports
=
[
1
;
2
];
oports
=
[
3
];
traced
=
[]
;
delays
=
[]
;
nodes
=
[(
0
,
4
,
0
);
(
0
,
5
,
9
);
(
2
,
6
,
1
)];
labels
=
id_empty
|>
id_add
4
(
Gate
Fork
)
|>
id_add
5
(
Gate
Join
)
|>
id_add
6
(
Gate
(
Box
"Test"
));
edges
=
[
(
1
,
None
,
4
,
None
);
(
2
,
None
,
5
,
None
);
(
4
,
None
,
6
,
Some
1
);
(
5
,
None
,
6
,
Some
2
);
(
6
,
Some
1
,
3
,
None
)
]
};;
let
dot_of_ptg
ptg
=
let
init_rank
=
rank_group
"min"
ptg
.
iports
in
...
...
@@ -284,21 +253,48 @@ let newid () =
let
newids
n
=
Utils
.
range
n
|>
List
.
map
(
fun
_
->
newid
()
);;
(** Duplique un ptg **)
(** TEMPORARY FUNCTIONS **)
let
make_arrow
x
y
=
(
x
,
None
,
y
,
None
);;
(** Working on edges **)
let
is_from
~
node
:
n
~
edge
:
e
=
match
e
with
|
(
a
,_,_,_
)
->
a
=
n
;;
let
is_to
~
node
:
n
~
edge
:
e
=
match
e
with
|
(
_
,_,
a
,_
)
->
a
=
n
;;
let
is_from_l
~
nodes
:
l
~
edge
:
e
=
List
.
exists
(
fun
x
->
is_from
x
e
)
l
;;
let
is_to_l
~
nodes
:
l
~
edge
:
e
=
List
.
exists
(
fun
x
->
is_to
x
e
)
l
;;
let
set_from
~
node
:
n
~
edge
:
(
x
,
y
,
z
,
t
)
=
(
n
,
y
,
z
,
t
);;
let
set_to
~
node
:
n
~
edge
:
(
x
,
y
,
z
,
t
)
=
(
x
,
y
,
n
,
t
);;
(**
* Create a copy of the ptg with
* a disjoint set of nodes
* along with the translation function
*)
let
replicate
ptg
=
let
translate
x
=
x
+
ptg
.
maxid
in
let
m
=
!
counter
in
let
translate
x
=
x
+
m
+
1
in
let
update_label
m
(
oldid
,
lbl
)
=
id_add
(
translate
oldid
)
lbl
m
in
counter
:=
translate
!
counter
;
counter
:=
translate
m
;
(
translate
,
{
maxid
=
translate
ptg
.
maxid
;
iports
=
List
.
map
translate
ptg
.
iports
;
oports
=
List
.
map
translate
ptg
.
i
ports
;
oports
=
List
.
map
translate
ptg
.
o
ports
;
traced
=
List
.
map
translate
ptg
.
traced
;
delays
=
List
.
map
translate
ptg
.
delays
;
...
...
@@ -315,70 +311,90 @@ let replicate ptg =
});;
(** Working on edges **)
let
is_from
~
node
:
n
~
edge
:
e
=
match
e
with
|
(
a
,_,_,_
)
->
a
=
n
;;
let
pre_nodes
~
node
:
n
t
=
t
.
edges
|>
List
.
filter
(
fun
e
->
is_to
~
node
:
n
~
edge
:
e
);;
let
is_to
~
node
:
n
~
edge
:
e
=
match
e
with
|
(
_
,_,
a
,_
)
->
a
=
n
;;
let
post_nodes
~
node
:
n
t
=
t
.
edges
|>
List
.
filter
(
fun
e
->
is_from
~
node
:
n
~
edge
:
e
);;
let
is_from_l
~
nodes
:
l
~
edge
:
e
=
List
.
exists
(
fun
x
->
is_from
x
e
)
l
;;
let
is_to_l
~
nodes
:
l
~
edge
:
e
=
List
.
exists
(
fun
x
->
is_to
x
e
)
l
;;
let
remove_node
~
node
:
n
t
=
let
node_rem
(
_
,
x
,_
)
=
not
(
x
=
n
)
in
let
simple_rem
x
=
not
(
x
=
n
)
in
let
edge_rem
e
=
(
is_from
~
node
:
n
~
edge
:
e
)
||
(
is_to
~
node
:
n
~
edge
:
e
)
in
let
set_from
~
node
:
n
~
edge
:
(
x
,
y
,
z
,
t
)
=
(
n
,
y
,
z
,
t
);;
let
set_to
~
node
:
n
~
edge
:
(
x
,
y
,
z
,
t
)
=
(
x
,
y
,
n
,
t
);;
{
edges
=
List
.
filter
edge_rem
t
.
edges
;
nodes
=
List
.
filter
node_rem
t
.
nodes
;
iports
=
List
.
filter
simple_rem
t
.
iports
;
oports
=
List
.
filter
simple_rem
t
.
oports
;
traced
=
List
.
filter
simple_rem
t
.
traced
;
delays
=
List
.
filter
simple_rem
t
.
delays
;
(** Split the trace of a pTG
labels
=
id_remove
n
t
.
labels
};;
(**
*
**)
let
split_trace
ptg
=
let
trids
=
newids
(
List
.
length
ptg
.
traced
)
in
let
corres
=
List
.
combine
ptg
.
traced
trids
in
let
edge_mod
(
oldt
,
newt
)
e
=
if
is_from
~
node
:
oldt
~
edge
:
e
then
set_from
~
node
:
newt
~
edge
:
e
else
e
* Remove a _main_ node
*
* Create new Disconnect for the pre
* Create new Bottoms for the post
*
* --> this way the circuit is always
* correct : no strange modifications
*
* *)
let
remove_node_safe
~
node
:
n
t
=
let
bottoms
=
ref
[]
in
let
discard
=
ref
[]
in
let
new_bottom
()
=
let
x
=
newid
()
in
bottoms
:=
x
::
!
bottoms
;
x
in
let
update_edges
l
p
=
l
|>
List
.
map
(
edge_mod
p
)
let
new_discard
()
=
let
x
=
newid
()
in
discard
:=
x
::
!
discard
;
x
in
let
traced_to_main
x
=
(
1
,
x
,
1
)
in
(
corres
,
{
ptg
with
maxid
=
!
counter
;
traced
=
[]
;
nodes
=
List
.
map
traced_to_main
(
ptg
.
traced
@
trids
)
@
ptg
.
nodes
;
edges
=
List
.
fold_left
update_edges
ptg
.
edges
corres
;
});;
(** Remove a _main_ node *)
let
remove_node
~
node
:
n
t
=
let
edge_rem
e
=
not
(
is_from
~
node
:
n
~
edge
:
e
||
is_to
~
node
:
n
~
edge
:
e
)
let
edge_mod
e
=
if
is_from
~
node
:
n
~
edge
:
e
then
let
(
_
,_,
x
,
i
)
=
e
in
(
new_bottom
()
,
None
,
x
,
i
)
else
if
is_to
~
node
:
n
~
edge
:
e
then
let
(
x
,
i
,_,_
)
=
e
in
(
x
,
i
,
new_discard
()
,
None
)
else
e
in
let
node_rem
(
_
,
x
,_
)
=
not
(
x
=
n
)
in
let
simple_rem
x
=
not
(
x
=
n
)
in
let
add_bottoms
l
=
List
.
fold_left
(
fun
a
b
->
id_add
b
(
Value
Bottom
)
a
)
l
!
bottoms
in
let
add_discard
l
=
List
.
fold_left
(
fun
a
b
->
id_add
b
(
Gate
Disconnect
)
a
)
l
!
discard
in
{
t
with
edges
=
List
.
filter
edge_rem
t
.
edges
;
nodes
=
List
.
filter
node_rem
t
.
nodes
;
edges
=
List
.
map
edge_mod
t
.
edges
;
nodes
=
List
.
map
(
fun
x
->
(
0
,
x
,
0
))
!
bottoms
@
List
.
map
(
fun
x
->
(
0
,
x
,
0
))
!
discard
@
List
.
filter
node_rem
t
.
nodes
;
traced
=
List
.
filter
simple_rem
t
.
traced
;
delays
=
List
.
filter
simple_rem
t
.
delays
;
oports
=
List
.
filter
simple_rem
t
.
oports
;
iports
=
List
.
filter
simple_rem
t
.
iports
;
labels
=
t
.
labels
|>
id_remove
n
;
labels
=
t
.
labels
|>
id_remove
n
|>
add_bottoms
|>
add_discard
};;
let
pre_nodes
~
node
:
n
t
=
t
.
edges
|>
List
.
filter
(
fun
e
->
is_to
~
node
:
n
~
edge
:
e
);;
let
post_nodes
~
node
:
n
t
=
t
.
edges
|>
List
.
filter
(
fun
e
->
is_from
~
node
:
n
~
edge
:
e
);;
let
relabel_node
~
node
:
n
~
label
:
l
t
=
{
...
...
@@ -388,6 +404,9 @@ let relabel_node ~node:n ~label:l t =
|>
id_add
n
l
};;
let
relabel_l
~
nodes
:
ns
~
label
:
l
t
=
List
.
fold_left
(
fun
b
a
->
relabel_node
~
node
:
a
~
label
:
l
b
)
t
ns
;;
(** adding an edge
*
* Does not include sanity checks
...
...
@@ -399,6 +418,17 @@ let add_edge ~edge:e t =
edges
=
e
::
t
.
edges
};;
let
add_node
~
node
:
e
t
=
{
t
with
nodes
=
(
0
,
e
,
0
)
::
t
.
nodes
};;
let
add_nodes
~
nodes
:
l
t
=
List
.
fold_left
(
fun
a
b
->
add_node
~
node
:
b
a
)
t
l
;;
(**
* Try moving a node to main,
* does nothing if main already exists
...
...
@@ -408,7 +438,7 @@ let move_to_main ~node:n t =
let
simple_rem
x
=
not
(
x
=
n
)
in
if
try_find
=
[]
then
{
t
with
nodes
=
(
1
,
n
,
1
)
::
t
.
nodes
;
nodes
=
(
0
,
n
,
0
)
::
t
.
nodes
;
traced
=
List
.
filter
simple_rem
t
.
traced
;
delays
=
List
.
filter
simple_rem
t
.
delays
;
oports
=
List
.
filter
simple_rem
t
.
oports
;
...
...
@@ -417,6 +447,75 @@ let move_to_main ~node:n t =
else
t
;;
let
flatten_ptg
g
=
let
others
=
g
.
iports
@
g
.
oports
@
g
.
traced
@
g
.
delays
in
List
.
fold_left
(
fun
a
b
->
move_to_main
~
node
:
b
a
)
g
others
;;
let
merger_v
k
x
y
=
match
x
with
|
Some
v
->
Some
v
|
None
->
y
;;
(**
* The two graphs have
* distinct node names
*)
let
ptg_merge
g1
g2
=
{
nodes
=
(
flatten_ptg
g1
)
.
nodes
@
(
flatten_ptg
g2
)
.
nodes
;
delays
=
[]
;
traced
=
[]
;
iports
=
[]
;
oports
=
[]
;
labels
=
id_merge
merger_v
g1
.
labels
g2
.
labels
;
edges
=
g1
.
edges
@
g2
.
edges
;
};;
(** Dispatch nodes *)
let
dispatch_with
~
f
~
from1
~
from2
~
fst
~
snd
g
=
let
make_edge
a
b
c
d
=
if
f
c
d
g
then
[
(
a
,
None
,
c
,
None
);
(
b
,
None
,
d
,
None
)
]
else
[
(
b
,
None
,
c
,
None
);
(
a
,
None
,
d
,
None
)
]
in
{
g
with
edges
=
List
.
concat
(
zip_with_4
make_edge
from1
from2
fst
snd
)
@
g
.
edges
};;
let
set_inputs
~
nodes
:
l
ptg
=
{
ptg
with
iports
=
l
};;
let
set_outputs
~
nodes
:
l
ptg
=
{
ptg
with
oports
=
l
};;
let
set_delays
~
nodes
:
l
ptg
=
{
ptg
with
delays
=
l
};;
let
set_trace
~
nodes
:
l
ptg
=
{
ptg
with
traced
=
l
};;
(**
* Checks if a node is in the main
* graph (not special set)
...
...
@@ -431,6 +530,97 @@ let delete_label ~node:n t =
labels
=
t
.
labels
|>
id_remove
n
};;
let
delete_label_l
~
nodes
:
n
t
=
List
.
fold_left
(
fun
a
b
->
delete_label
~
node
:
b
a
)
t
n
;;
let
connect
~
from
:
i
~
towards
:
j
ptg
=
{
ptg
with
edges
=
zip_with
make_arrow
i
j
@
ptg
.
edges
};;
let
mk_join
~
towards
~
fst
~
snd
ptg
=
let
new_joins
=
newids
(
List
.
length
towards
)
in
ptg
|>
add_nodes
~
nodes
:
new_joins
|>
connect
~
from
:
fst
~
towards
:
new_joins
|>
connect
~
from
:
snd
~
towards
:
new_joins
|>
connect
~
from
:
new_joins
~
towards
:
towards
|>
relabel_l
~
nodes
:
new_joins
~
label
:
(
Gate
Join
);;
let
mk_fork
~
from
~
fst
~
snd
ptg
=
let
new_forks
=
newids
(
List
.
length
from
)
in
ptg
|>
add_nodes
~
nodes
:
new_forks
|>
connect
~
from
:
new_forks
~
towards
:
fst
|>
connect
~
from
:
new_forks
~
towards
:
snd
|>
connect
~
from
:
from
~
towards
:
new_forks
|>
relabel_l
~
nodes
:
new_forks
~
label
:
(
Gate
Fork
);;
let
rec
fork_into
~
node
:
n
~
nodes
:
l
ptg
=
match
l
with
|
[]
->
ptg
|
[
t
]
->
ptg
|>
add_edge
~
edge
:
(
n
,
None
,
t
,
None
)
|
t
::
q
->
let
fork_node
=
newid
()
in
ptg
|>
fork_into
~
node
:
fork_node
~
nodes
:
q
|>
add_node
~
node
:
fork_node
|>
relabel_node
~
node
:
fork_node
~
label
:
(
Gate
Fork
)
|>
add_edge
~
edge
:
(
fork_node
,
None
,
t
,
None
)
|>
add_edge
~
edge
:
(
n
,
None
,
fork_node
,
None
);;
let
rec
join_into
~
node
:
n
~
nodes
:
l
ptg
=
match
l
with
|
[]
->
ptg
|
[
t
]
->
ptg
|>
add_edge
~
edge
:
(
t
,
None
,
n
,
None
)
|
t
::
q
->
let
join_node
=
newid
()
in
ptg
|>
join_into
~
node
:
join_node
~
nodes
:
q
|>
add_node
~
node
:
join_node
|>
relabel_node
~
node
:
join_node
~
label
:
(
Gate
Join
)
|>
add_edge
~
edge
:
(
t
,
None
,
join_node
,
None
)
|>
add_edge
~
edge
:
(
join_node
,
None
,
n
,
None
);;
(** Split the trace of a pTG
*
**)
let
split_trace
ptg
=
let
trids
=
newids
(
List
.
length
ptg
.
traced
)
in
let
corres
=
List
.
combine
ptg
.
traced
trids
in
let
edge_mod
(
oldt
,
newt
)
e
=
if
is_from
~
node
:
oldt
~
edge
:
e
then
set_from
~
node
:
newt
~
edge
:
e
else
e
in
let
update_edges
l
p
=
l
|>
List
.
map
(
edge_mod
p
)
in
let
traced_to_main_left
x
=
(
0
,
x
,
0
)
in
let
traced_to_main_right
x
=
(
0
,
x
,
0
)
in
(
trids
,
ptg
.
traced
,
{
ptg
with
traced
=
[]
;
nodes
=
List
.
map
traced_to_main_left
ptg
.
traced
@
List
.
map
traced_to_main_right
trids
@
ptg
.
nodes
;
edges
=
List
.
fold_left
update_edges
ptg
.
edges
corres
;
});;
(***
* The original PTG does not have any trace
*)
let
connect_trace
~
from
:
i
~
towards
:
j
ptg
=
let
new_trace
=
newids
(
List
.
length
i
)
in
ptg
|>
connect
~
from
:
i
~
towards
:
new_trace
|>
connect
~
from
:
new_trace
~
towards
:
j
|>
set_trace
~
nodes
:
new_trace
;;
(**
* Change a node's signature
* and the edges according to
...
...
@@ -470,6 +660,7 @@ let signature_node ~node:n ~ins:i ~outs:j t =
(**
* pass a constant node through
* a simple node
* the node can be a traced one
*)
let
propagate_constant
~
node
:
n
t
=
match
id_find
n
t
.
labels
with
...
...
@@ -483,7 +674,7 @@ let propagate_constant ~node:n t =
|
None
->
false
|
Some
_
->
true
in
(*
(*
* replace the node if and only if there is
* only us on the node, and it is a non-labeled
* node
...
...
@@ -507,14 +698,17 @@ let propagate_constant ~node:n t =
let
simplify_identity
~
node
:
n
t
=
match
id_find
n
t
.
labels
with
|
None
->
begin
(* an unlabeled node is ALWAYS an identity *)
let
[
x
,
i
,_,_
]
=
pre_nodes
~
node
:
n
t
in
let
[
_
,_,
y
,
j
]
=
post_nodes
~
node
:
n
t
in
if
is_main_node
~
node
:
x
t
&&
is_main_node
~
node
:
y
t
then
t
|>
remove_node
~
node
:
n
|>
add_edge
~
edge
:
(
x
,
i
,
y
,
j
)
else
t
begin
try
let
[
x
,
i
,_,_
]
=
pre_nodes
~
node
:
n
t
in
let
[
_
,_,
y
,
j
]
=
post_nodes
~
node
:
n
t
in
if
is_main_node
~
node
:
x
t
&&
is_main_node
~
node
:
y
t
then
t
|>
remove_node
~
node
:
n
|>
add_edge
~
edge
:
(
x
,
i
,
y
,
j
)
else
t
with
Match_failure
_
->
t
end
|
Some
_
->
t
;;
...
...
@@ -553,14 +747,14 @@ let reduce_mux ~node:mux t =
in
match
v1
with
|
Top
->
first
|>
relabel_node
~
node
:
p2
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
p3
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
mux
~
label
:
(
Value
Top
)
first
|>
relabel_node
~
node
:
p2
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
p3
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
mux
~
label
:
(
Value
Top
)
|>
signature_node
~
node
:
mux
~
ins
:
0
~
outs
:
0
|
Bottom
->
first
|>
relabel_node
~
node
:
p2
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
p3
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
mux
~
label
:
(
Value
Bottom
)
first
|>
relabel_node
~
node
:
p2
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
p3
~
label
:
(
Gate
Disconnect
)
|>
relabel_node
~
node
:
mux
~
label
:
(
Value
Bottom
)
|>
signature_node
~
node
:
mux
~
ins
:
0
~
outs
:
0
|
Low
->
first
...
...
@@ -575,55 +769,283 @@ let reduce_mux ~node:mux t =
|
_
->
t
;;
let
join_values
a
b
=
match
a
,
b
with
|
Bottom
,_
->
b
|
_
,
Bottom
->
a
|
High
,
Low
->
Top
|
Low
,
High
->
Top
|
Top
,_
->
Top
|
_
,
Top
->
Top
|
_
->
a
;;
(* otherwise a = b = join a b *)
(* TODO nmos & pmos table *)
let
nmos_values
a
b
=
a
;;
let
pmos_values
a
b
=
a
;;
let
function_of_gate
=
function
|
Join
->
join_values
|
Nmos
->
nmos_values
|
Pmos
->
pmos_values
;;
let
reduce_gate
~
node
:
n
ptg
=
match
id_find
n
ptg
.
labels
with
|
Some
(
Gate
Mux
)
->
reduce_mux
~
node
:
n
ptg
|
Some
(
Gate
g
)
when
List
.
mem
g
[
Join
;
Nmos
;
Pmos
]
->
begin
let
inputs
=
pre_nodes
~
node
:
n
ptg
in
let
trait_inpt
(
x
,
j
,_,
i
)
=
(
j
,
x
,
i
,
id_find
x
ptg
.
labels
)
in
let
compare_input
(
_
,_,
i
,_
)
(
_
,_,
j
,_
)
=
compare
i
j
in
let
real_inputs
=
inputs
|>
List
.
map
trait_inpt
|>
List
.
sort
compare_input
|>
List
.
map
(
fun
(
j
,
x
,_,
y
)
->
(
j
,
x
,
y
))
in
match
real_inputs
with
|
[(
_
,
p1
,
Some
(
Value
v1
));
(
k2
,
p2
,
Some
(
Value
v2
))
]
->
begin
ptg
|>
remove_node
~
node
:
p1
|>
remove_node
~
node
:
p2
|>
signature_node
~
node
:
n
~
ins
:
0
~
outs
:
0
(** set regular node **)
|>
relabel_node
~
node
:
n
~
label
:
(
Value
(
function_of_gate
g
v1
v2
))
end
(* TODO pmos AND nmos short circuit *)
(* TODO join short circuit too *)
|
_
->
ptg
let
reduce_times
ptg1
=
let
ptg2
=
replicate
ptg1
in
let
new_inputs
=
...
in
dispatch
f
new_inputs
ptg1
.
inputs
ptg2
.
inputs
end
|
_
->
ptg
;;
mk_join
new_outputs
ptg1
.
outputs
ptg2
.
outputs
relabel
ptg1
.
outputs
DELAY
let
yank_constant
~
node
:
n
ptg
=
match
id_find
n
ptg
.
labels
with
|
Some
(
Value
v
)
->
begin
match
post_nodes
~
node
:
n
ptg
with
|
[(
_
,_,
t
,_
)]
->
if
List
.
mem
t
ptg
.
traced
then