Introduction

See https://guitarvydas.github.io/2021/05/03/Software-Components-101.html for an introduction to the examples shown below.

github

https://github.com/guitarvydas/basicdasl


Query Code

conn(Component,[Sender|SendingPort],[ReceivingComponent|ReceivingPort]) :-

    connection(Component,ConnectionID),

    sender(ConnectionID,SenderPairID),

    pp(SenderPairID,SendingPort),

    pc(SenderPairID,Sender),

    receiver(ConnectionID,ReceiverPairID),

    pc(ReceiverPairID,ReceivingComponent),

    pp(ReceiverPairID,ReceivingPort).


allReceivers(Component,S,R) :-

    setof(Receivers,conn(Component,S,Receivers),R).


conn(Component,'-->'(S,RBag)):-

    allReceivers(Component, S, RBag).


conn(':'(C,W)) :-

    conn(C,W).


The conn/1 query results in one connection (W) for a given component (C).


We repeat the query at the REPL (using semi-colon) to get all connections on a diagram.


[It is possible to write a query that returns all connections for all components, but the REPL version is sufficient for this essay.]


Each sender and each receiver is represented by a pair.  Each pair is given a unique ID and each pair consists of two parts pc and pp, pair-component and pair-port, resp.

Basic

diagram

Image

Fig. 1 Basic Component

Dasl (basic1)

=== signatures

[main] < (in) > (out)

=== components

[main]

  []

=== connections

[main]

  [

    [.].(in) -> [.].(out)

  ]


Factbase





component("main",nil).

connection("main",n0).

inputPort("main","in").

outputPort("main","out").

pc(pair1,".").

pc(pair2,".").

pp(pair1,"in").

pp(pair2,"out").

receiver(n0,pair2).

sender(n0,pair1).


Queries

?- consult(fb).

true.


?- consult(q).

true.


?- conn(X).

X = "main":(["."|"in"]-->[["."|"out"]]).


?- 

Nested

diagram

Image

Fig. 2 Nested Component


Dasl (basic2)

=== signatures

[main] < (in) > (out)

=== components

[main]

  [ [subcomponent] ]

=== connections

[main]

  [

    [.].(in) -> [subcomponent].(A)

    [subcomponent].(B) -> [.].(out)

  ]


=== signatures

[subcomponent] < (A) > (B)

=== components

[subcomponent]

  []

=== connections

[subcomponent]

  []

  

Factbase







component("main",nil).

component("subcomponent",nil).

connection("main",n0).

connection("main",n3).

contains("main","subcomponent").

inputPort("main","in").

inputPort("subcomponent","A").

outputPort("main","out").

outputPort("subcomponent","B").

pc(pair1,".").

pc(pair2,"subcomponent").

pc(pair4,"subcomponent").

pc(pair5,".").

pp(pair1,"in").

pp(pair2,"A").

pp(pair4,"B").

pp(pair5,"out").

receiver(n0,pair2).

receiver(n3,pair5).

sender(n0,pair1).

sender(n3,pair4).


Queries

?- consult(fb).

true.


?- consult(q).

true.


?- conn(X).

X = "main":(["."|"in"]-->[["subcomponent"|"A"]]) ;

X = "main":(["subcomponent"|"B"]-->[["."|"out"]]).


?- 

Nested Component Nested Inside a Nested Component-1

diagram

Image

Fig. 3 Component Nested in a Nested Component

Dasl (basic3)

=== signatures

[main] < (in) > (out)

=== components

[main]

  [ [subcomponent] ]

=== connections

[main]

  [

    [.].(in) -> [subcomponent].(A)

    [subcomponent].(B) -> [.].(out)

  ]


=== signatures

[subcomponent] < (A) > (*#)

=== components

[subcomponent]

  [ [component X] ]

=== connections

[subcomponent]

  [

    [.].(A) -> [component X].(c)

    [component X].(#) -> [.].(*#)

  ]


=== signatures

[component X] < (c) > (#)

=== components

[component X]

  []

=== connections

[component X]

  []


Factbase









component("component_X",nil).

component("main",nil).

component("subcomponent",nil).

connection("main",n0).

connection("main",n3).

connection("subcomponent",n6).

connection("subcomponent",n9).

contains("main","subcomponent").

contains("subcomponent","component_X").

inputPort("component_X","c").

inputPort("main","in").

inputPort("subcomponent","A").

outputPort("component_X","o_").

outputPort("main","out").

outputPort("subcomponent","so_").

pc(pair1,".").

pc(pair10,"component_X").

pc(pair11,".").

pc(pair2,"subcomponent").

pc(pair4,"subcomponent").

pc(pair5,".").

pc(pair7,".").

pc(pair8,"component_X").

pp(pair1,"in").

pp(pair10,"o_").

pp(pair11,"so_").

pp(pair2,"A").

pp(pair4,"B").

pp(pair5,"out").

pp(pair7,"A").

pp(pair8,"c").

receiver(n0,pair2).

receiver(n3,pair5).

receiver(n6,pair8).

receiver(n9,pair11).

sender(n0,pair1).

sender(n3,pair4).

sender(n6,pair7).

sender(n9,pair10).


Queries

?- consult(fb).

true.


?- consult(q).

true.


?- conn(X).

X = "main":(["."|"in"]-->[["subcomponent"|"A"]]) ;

X = "main":(["subcomponent"|"so_"]-->[["."|"out"]]) ;

X = "subcomponent":(["."|"A"]-->[["component_X"|"c"]]) ;

X = "subcomponent":(["component_X"|"o_"]-->[["."|"so_"]]).


?- 

Copied Component

diagram

Image

Fig. 4 Copied Component

Dasl (basic4)

=== signatures

[main] < (in) > (out)

=== components

[main]

  [ [subcomponent] ]

=== connections

[main]

  [

    [.].(in) -> [1].(A),[2].(A)

    [1].(*#) -> [.].(out)

    [2].(*#) -> [.].(out)

  ]


=== signatures

[subcomponent] < (A) > (*#)

=== components

[subcomponent]

  [ [component X] ]

=== connections

[subcomponent]

  [

    [.].(A) -> [component X].(c)

    [component X].(#) -> [.].(*#)

  ]



=== signatures

[component X] < (c) > (#)

=== components

[component X]

  []

=== connections

[component X]

  []




Factbase









component("component_X",nil).

component("main",nil).

component("subcomponent",nil).

connection("main",n0).

connection("main",n4).

connection("main",n7).

connection("subcomponent",n10).

connection("subcomponent",n13).

contains("main","subcomponent").

contains("subcomponent","component_X").

inputPort("component_X","c").

inputPort("main","in").

inputPort("subcomponent","A").

outputPort("component_X","o_").

outputPort("main","out").

outputPort("subcomponent","so_").

pc(pair1,".").

pc(pair11,".").

pc(pair12,"component_X").

pc(pair14,"component_X").

pc(pair15,".").

pc(pair2,"1").

pc(pair3,"2").

pc(pair5,"1").

pc(pair6,".").

pc(pair8,"2").

pc(pair9,".").

pp(pair1,"in").

pp(pair11,"A").

pp(pair12,"c").

pp(pair14,"o_").

pp(pair15,"so_").

pp(pair2,"A").

pp(pair3,"A").

pp(pair5,"so_").

pp(pair6,"out").

pp(pair8,"so_").

pp(pair9,"out").

receiver(n0,pair2).

receiver(n0,pair3).

receiver(n10,pair12).

receiver(n13,pair15).

receiver(n4,pair6).

receiver(n7,pair9).

sender(n0,pair1).

sender(n10,pair11).

sender(n13,pair14).

sender(n4,pair5).

sender(n7,pair8).


Queries

?- consult(fb).

true.


?- consult(q).

true.


?- conn(X).

X = "main":(["."|"in"]-->[["1"|"A"], ["2"|"A"]]) ;

X = "main":(["1"|"so_"]-->[["."|"out"]]) ;

X = "main":(["2"|"so_"]-->[["."|"out"]]) ;

X = "subcomponent":(["."|"A"]-->[["component_X"|"c"]]) ;

X = "subcomponent":(["component_X"|"o_"]-->[["."|"so_"]]).


?- 

Squashed

diagram

Image

Fig. 5 Copied Component 


Diagram Fig. 5 is the same as Fig. 4.


At this point, we are not changing the diagram, we will only be changing the .dasl file…


Dasl (basic5)

=== signatures

[main] < (in) > (out)

[subcomponent] < (A) > (*#)

[component X] < (c) > (#)

=== components

[main]

  [ [subcomponent] ]

[subcomponent]

  [ [component X] ]

[component X]

  []

=== connections

[main]

  [

    [.].(in) -> [1].(A),[2].(A)

    [1].(*#) -> [.].(out)

    [2].(*#) -> [.].(out)

  ]

[subcomponent]

  [

    [.].(A) -> [component X].(c)

    [component X].(#) -> [.].(*#)

  ]

[component X]

  []


In this .dasl file, we squash all of the signatures / components / connections together, but, otherwise this .dasl file represents the same constructs as in Copied Component.

Factbase





component("component_X",nil).

component("main",nil).

component("subcomponent",nil).

connection("main",n0).

connection("main",n4).

connection("main",n7).

connection("subcomponent",n10).

connection("subcomponent",n13).

contains("main","subcomponent").

contains("subcomponent","component_X").

inputPort("component_X","c").

inputPort("main","in").

inputPort("subcomponent","A").

outputPort("component_X","o_").

outputPort("main","out").

outputPort("subcomponent","so_").

pc(pair1,".").

pc(pair11,".").

pc(pair12,"component_X").

pc(pair14,"component_X").

pc(pair15,".").

pc(pair2,"1").

pc(pair3,"2").

pc(pair5,"1").

pc(pair6,".").

pc(pair8,"2").

pc(pair9,".").

pp(pair1,"in").

pp(pair11,"A").

pp(pair12,"c").

pp(pair14,"o_").

pp(pair15,"so_").

pp(pair2,"A").

pp(pair3,"A").

pp(pair5,"so_").

pp(pair6,"out").

pp(pair8,"so_").

pp(pair9,"out").

receiver(n0,pair2).

receiver(n0,pair3).

receiver(n10,pair12).

receiver(n13,pair15).

receiver(n4,pair6).

receiver(n7,pair9).

sender(n0,pair1).

sender(n10,pair11).

sender(n13,pair14).

sender(n4,pair5).

sender(n7,pair8).


Queries

?- consult(fb).

true.


?- consult(q).

true.


?- conn(X).

X = "main":(["."|"in"]-->[["1"|"A"], ["2"|"A"]]) ;

X = "main":(["1"|"so_"]-->[["."|"out"]]) ;

X = "main":(["2"|"so_"]-->[["."|"out"]]) ;

X = "subcomponent":(["."|"A"]-->[["component_X"|"c"]]) ;

X = "subcomponent":(["component_X"|"o_"]-->[["."|"so_"]]).


?- 



The queries return the same results as in Copied Component.  We have changed nothing, except for the formatting (squashing) of the .dasl file.