Skip to content

Instantly share code, notes, and snippets.

@jarble
Last active January 22, 2020 19:10
Show Gist options
  • Save jarble/fe022eb63aa698f51200532be18b2c86 to your computer and use it in GitHub Desktop.
Save jarble/fe022eb63aa698f51200532be18b2c86 to your computer and use it in GitHub Desktop.
A simple demo of type inference in SWI-Prolog
:- initialization(main).
:- set_prolog_flag('double_quotes','chars').
main :- Term = (member(Z,A),append(A,B,C),dif(A,[true,false])),has_type(Term:Type,Types),writeln('Term with types to infer:'),writeln(Term),writeln('Types of variables in this term:'),writeln(Types).
greater_than(A,B) :-
A > B.
matches_any_([],B) :- false.
matches_any_([A|A1],B) :-
subsumes_term(A,B),A=B;matches_any_(A1,B).
matches_any(A,B) :-
nonvar(A),matches_any_(A,B).
has_type(Var:number,_) :-
number(Var).
has_type(Var:[list,_],_) :-
Var == [].
has_type([A|B]:[list,T],List) :-
is_list(B),
has_type(A:T,List),
has_type(B:[list,T],List).
has_type(Var:number,List) :-
matches_any([sin(A1),cos(A1),tan(A1)],Var),
has_type(A1:number,List).
has_type(Var:bool,List) :-
matches_any([not(A1)],Var),
has_type(A1:bool,List).
has_type(Var:bool,_) :-
Var==true;Var==false.
has_type(Var:bool,List) :-
matches_any([member(A,B)],Var),
has_type(B:[list,T],List),has_type(A:T,List).
has_type(Var:bool,List) :-
matches_any([append(A,B,C)],Var),
has_type(A:T,List),has_type(B:T,List),has_type(C:T,List),T = [list,_].
has_type(Var:bool,List) :-
matches_any([(A,B),(A;B),(A->B),forall(A,B)],Var),
has_type([A,B]:[list,bool],List).
has_type(Var:number,List) :-
matches_any([(A+B),(A-B),(A1*B),(A/B),A**B],Var),
has_type([A,B]:[list,number],List).
has_type(Var:bool,List) :-
matches_any([(A>B),(A<B),A>=B,A=<B],Var),
has_type([A,B]:[list,number],List).
has_type(Var:bool,List) :-
matches_any([(A==B),(A=B),(A \= B),(A \== B),dif(A,B)],Var),
has_type([A,B]:[list,_],List).
has_type(Vars,List) :-
var(List),List=[_|_],has_type(Vars,List).
has_type(Var:Type,[Var1|Rest]) :-
var(Var),
(Var:Type == Var1;var(Var),var(Var1),(Var:Type) = Var1;
nonvar(Var1),Var1=V1:T1,(V1==Var,Type=T1;
(V1 \== Var),has_type(Var:Type,Rest))).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment