2

I have data in the following form:

:-use_module(library(clpb)).
%inputs are ids that will have an associated boolean value. 
input(i1).
input(i2).
input(i3).
input(i4).
input(i5).
input(i6).
input(i7).
input(i8).
input(i9).
input(i10).
input(i11).
input(i12).
input(i13).
input(i14).
input(i15).
input(i16).
input(i17).
input(i18).
input(i19).
input(i20).
input(i21).
input(i22).
input(i23).

%and_gate(Id,ListOfInputs) the list of inputs can include other AND and/or  OR gates

and_gate(and1,[i1,i2,i3]).
and_gate(and2,[i4,i5,i6]).
and_gate(and3,[and1,and2,or1,or2,i7,i8]).
and_gate(and4,[or3,i9]).
and_gate(and5,[i15,i16,i17]).

%or_gate(Id,ListOfInputs) the list of inputs can include inputs as well as AND and/or OR gates
or_gate(or1,[i10,i11]).
or_gate(or2,[i12,i13]).
or_gate(or3,[or2,i14]).
or_gate(or4,[and5,i18,i19,i20]).

%device(ID,ListOfInputs) the list of inputs can include inputs as well as AND and/or OR gates
device(d1, [and3,and4,or3,or4]).
device(d2,[i21,i22,i23]).

Diagram: https://docs.google.com/drawings/d/10wBpmFxxbDqrlpPVqpkVo_r8I-qcalWAz7Lro9myjMs/edit?usp=sharing

Inputs into a device are also like an AND gate but they are always the 'top' level of the circuit tree. I want to implement a predicate that would result in something like:

?- device_structure(D,OnOFF,Sat,Inputs).
D=d1,
Sat = sat(OnOff =:= *([*([*([V1,V2,V3]),
                          *([V4,V5,V6]),V7,V8,+[V10,V11],+[V12,V13]
                         ]),
                       *([V9,+[V14,+[V12,V13]]]),
                       +[V14,+[V12,V13]],
                       +[*([V15,V16,V17]),V18,V19,V20]])),

Inputs =     [
      input(i1,V1),
      input(i2,V2),
      input(i3,V3),
      input(i4,V4),
      input(i5,V5),
      input(i6,V6),
      input(i7,V7),
      input(i8,V8),
      input(i9,V9),
      input(i10,V10),
      input(i11,V11),
      input(i12,V12),
      input(i13,V13),
      input(i14,V14),
      input(i15,V15),
      input(i16,V16),
      input(i17,V17),
      input(i18,V18),
      input(i19,V19),
      input(i20,V20)
     ]).

And then of course the much simpler structure for d2.

This would allow me to use the clpb library to both give an instantiation of inputs to know which devices are on or off or to find the inputs that need to be on for a device to be on.

However despite numerous attempts I have not been able to build these structures correctly.

The V variables don't need to be named like this but it is important that the variable in the sat statement matches the right input variable.

false
  • 10,264
  • 13
  • 101
  • 209
user27815
  • 4,767
  • 14
  • 28
  • 2
    Please try to get the syntax for a single example right, so that we can better understand what you are doing. For example, maybe this is closer to what you want to express: `sat(OnOff =:= *([ *([V1,V2,V3]), *([V4,V5,V6]),V7,V8,+[V10,V11],+[V12,V13],+[V9,+[+[V12,V13],V14]], +[+[V12,V13],V14], +[*([V15,V16,V17]),V18,V19,V20]])).`. Note that I can omit several parentheses: `+` is a prefix operator with the right priority, so I can simply write `+[A,B,C]` instead of `+([A,B,C])`, both denoting exactly the same as `A+B+C`. The conjunction `*([A,B,C])` must retain the outer parentheses though. – mat Sep 15 '15 at 13:03
  • When I try the above with CLP(B), I see from the residual goals that the truth value of the formula is independent of `V9` and `V14` by the way, so this can help to shorten the expression. To associate atoms with variables, you can simply use `Atom-Variable` pairs: Use `pairs_keys_values(Pairs, Keys, Values)` to introduce a new variable for each `Key` in `Keys`, and you can use `list_to_assoc/2` to build an association table for faster lookup of the variables corresponding to keys. – mat Sep 15 '15 at 13:07
  • I have edited the expression to what I think it should be.(Thanks for the tip or +[]). I have also inserted a diagram.(So you can see my working). The point is to build this formula automatically from the given data, so we dont have to scramble ours brains trying to write them manually! The predicate needs to return a list of input(id,Var) so i dont know if I gain something using 'pairs' . – user27815 Sep 15 '15 at 14:16
  • I think only v14 is independent? – user27815 Sep 15 '15 at 14:18
  • In your edit, you changed on of the `+` to `*`, so yes, in the current version, only `V14` is independent. – mat Sep 15 '15 at 14:22

1 Answers1

2

this seems to work, HTH

device_structure(D, OnOFF, Sat, Inputs) :-
    device(D, D_in),
    build(D_in, Structure, Inputs),
    Sat = sat(OnOFF =:= *(Structure)).

build([], [], []).
build([C|Cs], [V|R], Inputs) :-
    input(C),
    build(Cs, R, InputsR),
    inputs([C-V], InputsR, Inputs).
build([C|Cs], [+(OrStruct)|R], Inputs) :-
    or_gate(C, OrInputs),
    build(OrInputs, OrStruct, Inputs1),
    build(Cs, R, Inputs2),
    inputs(Inputs1, Inputs2, Inputs).
build([C|Cs], [*(AndStruct)|R], Inputs) :-
    and_gate(C, AndInputs),
    build(AndInputs, AndStruct, Inputs1),
    build(Cs, R, Inputs2),
    inputs(Inputs1, Inputs2, Inputs).

inputs(I1, I2, Inputs) :-
    append(I1, I2, I3),
    sort(I3, Inputs).

Inputs are like [i1-_Var1,...], to get variables you can use pairs_keys_values(InputPairs, _, Inputs).

CapelliC
  • 59,646
  • 5
  • 47
  • 90