To do so, you'd have to know at something about at least some sides and/or some angles from the start. Wouldn't it be neat if we could tell the computer what we know about the triangle and have it tell us how to find the rest? Let's code some Prolog do so this.
Some immediate questions arise: 1) how do we represent the knowledge of math and trig. in code? 2) How would we code a way of using this knowledge to explain to us how to solve the triangle? It turns out that Prolog is well suited to handle both of these issues.
We won't go so far as to try and have the computer 'discover' math on its own. We'll tell it the relationships that hold for a right triangle, and let it do what it wants with the relationships. There are two parts, 1) the trigonometry and 2) the mathematics.
rule
that works as shown here:
rule([c,a,b],'c^2=a^2+b^2')
means "if you know any two of c
, a
, or b
, you can use 'c^2=a^2+b^2'
to find the third."
rule([d,e],'d+e+90=180')
means "if you know either variable d
or e
, you can use 'd+e+90=180' to solve for the other."
rule([d,a,c],'sin(d)=a/c')
means "if you know any two of d
, a
, or c
, you can use 'sin(d)=a/c' to find the third."
advise([b,c]).
advise
clause. It works like this:
advise(Knowns) :-
: advise on how to solve the triangle. We have to put a list of things we know (a-e) into a list called Knowns
. So, doing goal: advice([b,c]).
tells the code to solve the triangle given that we already know side b
and c
.
rule(Needs,Advice)
line. This will put the needs of the rule (i.e. the list of variables it needs to work) into variable Needs
, and the textual advice for how the rule works into Advice
.
Needs
, to see how many variables it requires (this is $n$ in the discussion above).
Needs
and Knowns
. Remember, Needs
contains the variables the rule needs to work, and Knowns
is what we know about the triangle. intersection(Needs,Knowns,Int)
puts the variables that occur in both list Needs
and list Advice
into the list Int
. Any variable in either that is not in both will not appear in Int
. Hence Int
will be a list of variables the given rule needs that we may be able to solve for.
Int
is one less than the number of variables that this rule needs. (This is the $n-1$ check in the discussion above; we want to see if the number of variables we know is one lesss than those needed by a rule.) If this isn't true, the line length(Int,L1)
will fail and Prolog will go backwards in the logic chain and find another rule to work with.
subtract(Needs,Knowns,[CanNowSolveFor])
, we know all but one variable needed by the selected rule, so substracting Needs
from Knowns
will return just the new variable we can now solve for. It'll put it into the Prolog variable CanNowSolveFor
.
\+ member(CanNowSolveFor,Knowns)
means check that CanNowSolveFor
is not already known (\+
means "not" in Prolog).
append([CanNowSolveFor],Knowns,NewKnowns)
function.
!
, then call advise
again, with our newly updated and expanded list of known variables, so see what other trig. rule it may choose to work with.